gator: Version 5.19

Signed-off-by: Jon Medhurst <tixy@linaro.org>
diff --git a/tools/gator/daemon/MaliVideoDriver.cpp b/tools/gator/daemon/MaliVideoDriver.cpp
new file mode 100644
index 0000000..18b413b
--- /dev/null
+++ b/tools/gator/daemon/MaliVideoDriver.cpp
@@ -0,0 +1,253 @@
+/**
+ * Copyright (C) ARM Limited 2014. 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 "MaliVideoDriver.h"
+
+#include <unistd.h>
+
+#include "Buffer.h"
+#include "Counter.h"
+#include "Logging.h"
+#include "SessionData.h"
+
+// From instr/src/mve_instr_comm_protocol.h
+typedef enum mve_instr_configuration_type {
+	MVE_INSTR_RAW         = 1 << 0,
+	MVE_INSTR_COUNTERS    = 1 << 1,
+	MVE_INSTR_EVENTS      = 1 << 2,
+	MVE_INSTR_ACTIVITIES  = 1 << 3,
+
+	// Raw always pushed regardless
+	MVE_INSTR_PULL        = 1 << 12,
+	// Raw always unpacked regardless
+	MVE_INSTR_PACKED_COMM = 1 << 13,
+	// Don’t send ACKt response
+	MVE_INSTR_NO_AUTO_ACK   = 1 << 14,
+} mve_instr_configuration_type_t;
+
+static const char COUNTER[] = "ARM_Mali-V500_cnt";
+static const char EVENT[] = "ARM_Mali-V500_evn";
+static const char ACTIVITY[] = "ARM_Mali-V500_act";
+
+class MaliVideoCounter {
+public:
+	MaliVideoCounter(MaliVideoCounter *next, const char *name, const MaliVideoCounterType type, const int id) : mNext(next), mName(name), mType(type), mId(id), mKey(getEventKey()), mEnabled(false) {
+	}
+
+	~MaliVideoCounter() {
+		delete mName;
+	}
+
+	MaliVideoCounter *getNext() const { return mNext; }
+	const char *getName() const { return mName; }
+	MaliVideoCounterType getType() const { return mType; }
+	int getId() const { return mId; }
+	int getKey() const { return mKey; }
+	bool isEnabled() const { return mEnabled; }
+	void setEnabled(const bool enabled) { mEnabled = enabled; }
+
+private:
+	MaliVideoCounter *const mNext;
+	const char *const mName;
+	const MaliVideoCounterType mType;
+	// Mali Video id
+	const int mId;
+	// Streamline key
+	const int mKey;
+	bool mEnabled;
+};
+
+MaliVideoDriver::MaliVideoDriver() : mCounters(NULL), mActivityCount(0) {
+}
+
+MaliVideoDriver::~MaliVideoDriver() {
+	while (mCounters != NULL) {
+		MaliVideoCounter *counter = mCounters;
+		mCounters = counter->getNext();
+		delete counter;
+	}
+}
+
+void MaliVideoDriver::setup(mxml_node_t *const xml) {
+	// hwmon does not currently work with perf
+	if (gSessionData->perf.isSetup()) {
+		return;
+	}
+
+	mxml_node_t *node = xml;
+	while (true) {
+		node = mxmlFindElement(node, xml, "event", NULL, NULL, MXML_DESCEND);
+		if (node == NULL) {
+			break;
+		}
+		const char *counter = mxmlElementGetAttr(node, "counter");
+		if (counter == NULL) {
+			// Ignore
+		} else if (strncmp(counter, COUNTER, sizeof(COUNTER) - 1) == 0) {
+			const int i = strtol(counter + sizeof(COUNTER) - 1, NULL, 10);
+			mCounters = new MaliVideoCounter(mCounters, strdup(counter), MVCT_COUNTER, i);
+		} else if (strncmp(counter, EVENT, sizeof(EVENT) - 1) == 0) {
+			const int i = strtol(counter + sizeof(EVENT) - 1, NULL, 10);
+			mCounters = new MaliVideoCounter(mCounters, strdup(counter), MVCT_EVENT, i);
+		} else if (strcmp(counter, ACTIVITY) == 0) {
+			mCounters = new MaliVideoCounter(mCounters, strdup(ACTIVITY), MVCT_ACTIVITY, 0);
+			mActivityCount = 0;
+			while (true) {
+				char buf[32];
+				snprintf(buf, sizeof(buf), "activity%i", mActivityCount + 1);
+				if (mxmlElementGetAttr(node, buf) == NULL) {
+					break;
+				}
+				++mActivityCount;
+			}
+		}
+	}
+}
+
+MaliVideoCounter *MaliVideoDriver::findCounter(const Counter &counter) const {
+	for (MaliVideoCounter *maliVideoCounter = mCounters; maliVideoCounter != NULL; maliVideoCounter = maliVideoCounter->getNext()) {
+		if (strcmp(maliVideoCounter->getName(), counter.getType()) == 0) {
+			return maliVideoCounter;
+		}
+	}
+
+	return NULL;
+}
+
+bool MaliVideoDriver::claimCounter(const Counter &counter) const {
+	return findCounter(counter) != NULL;
+}
+
+bool MaliVideoDriver::countersEnabled() const {
+	for (MaliVideoCounter * counter = mCounters; counter != NULL; counter = counter->getNext()) {
+		if (counter->isEnabled()) {
+			return true;
+		}
+	}
+	return false;
+}
+
+void MaliVideoDriver::resetCounters() {
+	for (MaliVideoCounter * counter = mCounters; counter != NULL; counter = counter->getNext()) {
+		counter->setEnabled(false);
+	}
+}
+
+void MaliVideoDriver::setupCounter(Counter &counter) {
+	MaliVideoCounter *const maliVideoCounter = findCounter(counter);
+	if (maliVideoCounter == NULL) {
+		counter.setEnabled(false);
+		return;
+	}
+	maliVideoCounter->setEnabled(true);
+	counter.setKey(maliVideoCounter->getKey());
+}
+
+int MaliVideoDriver::writeCounters(mxml_node_t *root) const {
+	if (access("/dev/mv500", F_OK) != 0) {
+		return 0;
+	}
+
+	int count = 0;
+	for (MaliVideoCounter * counter = mCounters; counter != NULL; counter = counter->getNext()) {
+		mxml_node_t *node = mxmlNewElement(root, "counter");
+		mxmlElementSetAttr(node, "name", counter->getName());
+		++count;
+	}
+
+	return count;
+}
+
+void MaliVideoDriver::marshalEnable(const MaliVideoCounterType type, char *const buf, const size_t bufsize, int &pos) {
+	// size
+	int numEnabled = 0;
+	for (MaliVideoCounter * counter = mCounters; counter != NULL; counter = counter->getNext()) {
+		if (counter->isEnabled() && (counter->getType() == type)) {
+			++numEnabled;
+		}
+	}
+	Buffer::packInt(buf, bufsize, pos, numEnabled*sizeof(uint32_t));
+	for (MaliVideoCounter * counter = mCounters; counter != NULL; counter = counter->getNext()) {
+		if (counter->isEnabled() && (counter->getType() == type)) {
+			Buffer::packInt(buf, bufsize, pos, counter->getId());
+		}
+	}
+}
+
+bool MaliVideoDriver::start(const int mveUds) {
+	char buf[256];
+	int pos = 0;
+
+	// code - MVE_INSTR_STARTUP
+	buf[pos++] = 'C';
+	buf[pos++] = 'L';
+	buf[pos++] = 'N';
+	buf[pos++] = 'T';
+	// size
+	Buffer::packInt(buf, sizeof(buf), pos, sizeof(uint32_t));
+	// client_version_number
+	Buffer::packInt(buf, sizeof(buf), pos, 1);
+
+	// code - MVE_INSTR_CONFIGURE
+	buf[pos++] = 'C';
+	buf[pos++] = 'N';
+	buf[pos++] = 'F';
+	buf[pos++] = 'G';
+	// size
+	Buffer::packInt(buf, sizeof(buf), pos, 5*sizeof(uint32_t));
+	// configuration
+	Buffer::packInt(buf, sizeof(buf), pos, MVE_INSTR_COUNTERS | MVE_INSTR_EVENTS | MVE_INSTR_ACTIVITIES | MVE_INSTR_PACKED_COMM);
+	// communication_protocol_version
+	Buffer::packInt(buf, sizeof(buf), pos, 1);
+	// data_protocol_version
+	Buffer::packInt(buf, sizeof(buf), pos, 1);
+	// sample_rate - convert samples/second to ms/sample
+	Buffer::packInt(buf, sizeof(buf), pos, 1000/gSessionData->mSampleRate);
+	// live_rate - convert ns/flush to ms/flush
+	Buffer::packInt(buf, sizeof(buf), pos, gSessionData->mLiveRate/1000000);
+
+	// code - MVE_INSTR_ENABLE_COUNTERS
+	buf[pos++] = 'C';
+	buf[pos++] = 'F';
+	buf[pos++] = 'G';
+	buf[pos++] = 'c';
+	marshalEnable(MVCT_COUNTER, buf, sizeof(buf), pos);
+
+	// code - MVE_INSTR_ENABLE_EVENTS
+	buf[pos++] = 'C';
+	buf[pos++] = 'F';
+	buf[pos++] = 'G';
+	buf[pos++] = 'e';
+	marshalEnable(MVCT_EVENT, buf, sizeof(buf), pos);
+
+	/*
+	// code - MVE_INSTR_ENABLE_ACTIVITIES
+	buf[pos++] = 'C';
+	buf[pos++] = 'F';
+	buf[pos++] = 'G';
+	buf[pos++] = 'a';
+	// size
+	Buffer::packInt(buf, sizeof(buf), pos, mActivityCount*sizeof(uint32_t));
+	for (int i = 0; i < mActivityCount; ++i) {
+		// activity_id
+		Buffer::packInt(buf, sizeof(buf), pos, i);
+	}
+	*/
+
+	int written = 0;
+	while (written < pos) {
+		size_t bytes = ::write(mveUds, buf + written, pos - written);
+		if (bytes <= 0) {
+			logg->logMessage("%s(%s:%i): write failed", __FUNCTION__, __FILE__, __LINE__);
+			return false;
+		}
+		written += bytes;
+	}
+
+	return true;
+}