blob: 2db332d3e2e44a6261e1c611a7e679c5a71c506d [file] [log] [blame]
Jon Medhurste31266f2014-08-04 15:47:44 +01001/**
Jon Medhurstb1d07442015-05-08 12:04:18 +01002 * Copyright (C) ARM Limited 2014-2015. All rights reserved.
Jon Medhurste31266f2014-08-04 15:47:44 +01003 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include "MaliVideoDriver.h"
10
11#include <unistd.h>
12
13#include "Buffer.h"
14#include "Counter.h"
15#include "Logging.h"
16#include "SessionData.h"
17
18// From instr/src/mve_instr_comm_protocol.h
19typedef enum mve_instr_configuration_type {
20 MVE_INSTR_RAW = 1 << 0,
21 MVE_INSTR_COUNTERS = 1 << 1,
22 MVE_INSTR_EVENTS = 1 << 2,
23 MVE_INSTR_ACTIVITIES = 1 << 3,
24
25 // Raw always pushed regardless
26 MVE_INSTR_PULL = 1 << 12,
27 // Raw always unpacked regardless
28 MVE_INSTR_PACKED_COMM = 1 << 13,
29 // Don’t send ACKt response
30 MVE_INSTR_NO_AUTO_ACK = 1 << 14,
31} mve_instr_configuration_type_t;
32
33static const char COUNTER[] = "ARM_Mali-V500_cnt";
34static const char EVENT[] = "ARM_Mali-V500_evn";
35static const char ACTIVITY[] = "ARM_Mali-V500_act";
36
Jon Medhurst96b56152014-10-30 18:01:15 +000037class MaliVideoCounter : public DriverCounter {
Jon Medhurste31266f2014-08-04 15:47:44 +010038public:
Jon Medhurst96b56152014-10-30 18:01:15 +000039 MaliVideoCounter(DriverCounter *next, const char *name, const MaliVideoCounterType type, const int id) : DriverCounter(next, name), mType(type), mId(id) {
Jon Medhurste31266f2014-08-04 15:47:44 +010040 }
41
42 ~MaliVideoCounter() {
Jon Medhurste31266f2014-08-04 15:47:44 +010043 }
44
Jon Medhurste31266f2014-08-04 15:47:44 +010045 MaliVideoCounterType getType() const { return mType; }
46 int getId() const { return mId; }
Jon Medhurste31266f2014-08-04 15:47:44 +010047
48private:
Jon Medhurste31266f2014-08-04 15:47:44 +010049 const MaliVideoCounterType mType;
50 // Mali Video id
51 const int mId;
Jon Medhurste31266f2014-08-04 15:47:44 +010052};
53
Jon Medhurst96b56152014-10-30 18:01:15 +000054MaliVideoDriver::MaliVideoDriver() {
Jon Medhurste31266f2014-08-04 15:47:44 +010055}
56
57MaliVideoDriver::~MaliVideoDriver() {
Jon Medhurste31266f2014-08-04 15:47:44 +010058}
59
Jon Medhurst96b56152014-10-30 18:01:15 +000060void MaliVideoDriver::readEvents(mxml_node_t *const xml) {
Jon Medhurste31266f2014-08-04 15:47:44 +010061 mxml_node_t *node = xml;
62 while (true) {
63 node = mxmlFindElement(node, xml, "event", NULL, NULL, MXML_DESCEND);
64 if (node == NULL) {
65 break;
66 }
67 const char *counter = mxmlElementGetAttr(node, "counter");
68 if (counter == NULL) {
69 // Ignore
70 } else if (strncmp(counter, COUNTER, sizeof(COUNTER) - 1) == 0) {
71 const int i = strtol(counter + sizeof(COUNTER) - 1, NULL, 10);
Jon Medhurst96b56152014-10-30 18:01:15 +000072 setCounters(new MaliVideoCounter(getCounters(), strdup(counter), MVCT_COUNTER, i));
Jon Medhurste31266f2014-08-04 15:47:44 +010073 } else if (strncmp(counter, EVENT, sizeof(EVENT) - 1) == 0) {
74 const int i = strtol(counter + sizeof(EVENT) - 1, NULL, 10);
Jon Medhurst96b56152014-10-30 18:01:15 +000075 setCounters(new MaliVideoCounter(getCounters(), strdup(counter), MVCT_EVENT, i));
76 } else if (strncmp(counter, ACTIVITY, sizeof(ACTIVITY) - 1) == 0) {
77 const int i = strtol(counter + sizeof(ACTIVITY) - 1, NULL, 10);
78 setCounters(new MaliVideoCounter(getCounters(), strdup(counter), MVCT_ACTIVITY, i));
Jon Medhurste31266f2014-08-04 15:47:44 +010079 }
80 }
81}
82
Jon Medhurste31266f2014-08-04 15:47:44 +010083int MaliVideoDriver::writeCounters(mxml_node_t *root) const {
84 if (access("/dev/mv500", F_OK) != 0) {
85 return 0;
86 }
87
Jon Medhurst96b56152014-10-30 18:01:15 +000088 return super::writeCounters(root);
Jon Medhurste31266f2014-08-04 15:47:44 +010089}
90
91void MaliVideoDriver::marshalEnable(const MaliVideoCounterType type, char *const buf, const size_t bufsize, int &pos) {
92 // size
93 int numEnabled = 0;
Jon Medhurst96b56152014-10-30 18:01:15 +000094 for (MaliVideoCounter *counter = static_cast<MaliVideoCounter *>(getCounters()); counter != NULL; counter = static_cast<MaliVideoCounter *>(counter->getNext())) {
Jon Medhurste31266f2014-08-04 15:47:44 +010095 if (counter->isEnabled() && (counter->getType() == type)) {
96 ++numEnabled;
97 }
98 }
99 Buffer::packInt(buf, bufsize, pos, numEnabled*sizeof(uint32_t));
Jon Medhurst96b56152014-10-30 18:01:15 +0000100 for (MaliVideoCounter *counter = static_cast<MaliVideoCounter *>(getCounters()); counter != NULL; counter = static_cast<MaliVideoCounter *>(counter->getNext())) {
Jon Medhurste31266f2014-08-04 15:47:44 +0100101 if (counter->isEnabled() && (counter->getType() == type)) {
102 Buffer::packInt(buf, bufsize, pos, counter->getId());
103 }
104 }
105}
106
Jon Medhurst96b56152014-10-30 18:01:15 +0000107static bool writeAll(const int mveUds, const char *const buf, const int pos) {
108 int written = 0;
109 while (written < pos) {
110 size_t bytes = ::write(mveUds, buf + written, pos - written);
111 if (bytes <= 0) {
Jon Medhurstb1d07442015-05-08 12:04:18 +0100112 logg->logMessage("write failed");
Jon Medhurst96b56152014-10-30 18:01:15 +0000113 return false;
114 }
115 written += bytes;
116 }
117
118 return true;
119}
120
Jon Medhurste31266f2014-08-04 15:47:44 +0100121bool MaliVideoDriver::start(const int mveUds) {
122 char buf[256];
123 int pos = 0;
124
125 // code - MVE_INSTR_STARTUP
126 buf[pos++] = 'C';
127 buf[pos++] = 'L';
128 buf[pos++] = 'N';
129 buf[pos++] = 'T';
130 // size
131 Buffer::packInt(buf, sizeof(buf), pos, sizeof(uint32_t));
132 // client_version_number
133 Buffer::packInt(buf, sizeof(buf), pos, 1);
134
135 // code - MVE_INSTR_CONFIGURE
136 buf[pos++] = 'C';
137 buf[pos++] = 'N';
138 buf[pos++] = 'F';
139 buf[pos++] = 'G';
140 // size
141 Buffer::packInt(buf, sizeof(buf), pos, 5*sizeof(uint32_t));
142 // configuration
143 Buffer::packInt(buf, sizeof(buf), pos, MVE_INSTR_COUNTERS | MVE_INSTR_EVENTS | MVE_INSTR_ACTIVITIES | MVE_INSTR_PACKED_COMM);
144 // communication_protocol_version
145 Buffer::packInt(buf, sizeof(buf), pos, 1);
146 // data_protocol_version
147 Buffer::packInt(buf, sizeof(buf), pos, 1);
148 // sample_rate - convert samples/second to ms/sample
149 Buffer::packInt(buf, sizeof(buf), pos, 1000/gSessionData->mSampleRate);
150 // live_rate - convert ns/flush to ms/flush
151 Buffer::packInt(buf, sizeof(buf), pos, gSessionData->mLiveRate/1000000);
152
153 // code - MVE_INSTR_ENABLE_COUNTERS
154 buf[pos++] = 'C';
155 buf[pos++] = 'F';
156 buf[pos++] = 'G';
157 buf[pos++] = 'c';
158 marshalEnable(MVCT_COUNTER, buf, sizeof(buf), pos);
159
160 // code - MVE_INSTR_ENABLE_EVENTS
161 buf[pos++] = 'C';
162 buf[pos++] = 'F';
163 buf[pos++] = 'G';
164 buf[pos++] = 'e';
165 marshalEnable(MVCT_EVENT, buf, sizeof(buf), pos);
166
Jon Medhurste31266f2014-08-04 15:47:44 +0100167 // code - MVE_INSTR_ENABLE_ACTIVITIES
168 buf[pos++] = 'C';
169 buf[pos++] = 'F';
170 buf[pos++] = 'G';
171 buf[pos++] = 'a';
Jon Medhurst96b56152014-10-30 18:01:15 +0000172 marshalEnable(MVCT_ACTIVITY, buf, sizeof(buf), pos);
Jon Medhurste31266f2014-08-04 15:47:44 +0100173
Jon Medhurst96b56152014-10-30 18:01:15 +0000174 return writeAll(mveUds, buf, pos);
175}
Jon Medhurste31266f2014-08-04 15:47:44 +0100176
Jon Medhurst96b56152014-10-30 18:01:15 +0000177void MaliVideoDriver::stop(const int mveUds) {
178 char buf[8];
179 int pos = 0;
180
181 // code - MVE_INSTR_STOP
182 buf[pos++] = 'S';
183 buf[pos++] = 'T';
184 buf[pos++] = 'O';
185 buf[pos++] = 'P';
186 marshalEnable(MVCT_COUNTER, buf, sizeof(buf), pos);
187
188 writeAll(mveUds, buf, pos);
189
190 close(mveUds);
Jon Medhurste31266f2014-08-04 15:47:44 +0100191}