From ed6e65a66f3bcf84dff4ff4e680096b7e40076d5 Mon Sep 17 00:00:00 2001 From: Philippe Langlais Date: Thu, 24 May 2012 17:15:43 +0200 Subject: Revert "Merge remote-tracking branch 'armlt/previous-armlt-gator' into stable-linux-ux500-3.3" This reverts commit a394b8c66756934bf0bc526da1b888e524313fb4, reversing changes made to a416f0c1e67d56752c38d8db621be99b3cf12bb8. --- drivers/Kconfig | 2 - drivers/Makefile | 2 - drivers/gator/daemon/Android.mk | 34 - drivers/gator/daemon/CapturedXML.cpp | 97 -- drivers/gator/daemon/CapturedXML.h | 23 - drivers/gator/daemon/Child.cpp | 304 ------ drivers/gator/daemon/Child.h | 35 - drivers/gator/daemon/Collector.cpp | 281 ------ drivers/gator/daemon/Collector.h | 39 - drivers/gator/daemon/ConfigurationXML.cpp | 156 --- drivers/gator/daemon/ConfigurationXML.h | 29 - drivers/gator/daemon/Fifo.cpp | 103 -- drivers/gator/daemon/Fifo.h | 41 - drivers/gator/daemon/LocalCapture.cpp | 208 ---- drivers/gator/daemon/LocalCapture.h | 27 - drivers/gator/daemon/Logging.cpp | 79 -- drivers/gator/daemon/Logging.h | 45 - drivers/gator/daemon/Makefile | 40 - drivers/gator/daemon/OlySocket.cpp | 257 ----- drivers/gator/daemon/OlySocket.h | 38 - drivers/gator/daemon/OlyUtility.cpp | 167 ---- drivers/gator/daemon/OlyUtility.h | 35 - drivers/gator/daemon/RequestXML.cpp | 61 -- drivers/gator/daemon/RequestXML.h | 33 - drivers/gator/daemon/Sender.cpp | 106 -- drivers/gator/daemon/Sender.h | 38 - drivers/gator/daemon/SessionData.cpp | 103 -- drivers/gator/daemon/SessionData.h | 68 -- drivers/gator/daemon/SessionXML.cpp | 119 --- drivers/gator/daemon/SessionXML.h | 40 - drivers/gator/daemon/StreamlineSetup.cpp | 321 ------ drivers/gator/daemon/StreamlineSetup.h | 46 - drivers/gator/daemon/XMLOut.cpp | 175 ---- drivers/gator/daemon/XMLOut.h | 45 - drivers/gator/daemon/XMLReader.cpp | 164 --- drivers/gator/daemon/XMLReader.h | 27 - drivers/gator/daemon/configuration.xml | 39 - drivers/gator/daemon/events-ARM11.xml | 43 - drivers/gator/daemon/events-ARM11MPCore.xml | 30 - drivers/gator/daemon/events-Cortex-A15.xml | 77 -- drivers/gator/daemon/events-Cortex-A5.xml | 39 - drivers/gator/daemon/events-Cortex-A7.xml | 50 - drivers/gator/daemon/events-Cortex-A8.xml | 58 -- drivers/gator/daemon/events-Cortex-A9.xml | 67 -- drivers/gator/daemon/events-Krait-architected.xml | 28 - drivers/gator/daemon/events-L2C-310.xml | 21 - drivers/gator/daemon/events-Linux.xml | 16 - drivers/gator/daemon/events-Mali-400.xml | 395 -------- drivers/gator/daemon/events-Scorpion.xml | 113 --- drivers/gator/daemon/events-ScorpionMP.xml | 96 -- drivers/gator/daemon/events_footer.xml | 1 - drivers/gator/daemon/events_header.xml | 2 - drivers/gator/daemon/main.cpp | 306 ------ drivers/gator/driver/Kconfig | 7 - drivers/gator/driver/Makefile | 56 -- drivers/gator/driver/gator.h | 99 -- drivers/gator/driver/gator_annotate.c | 181 ---- drivers/gator/driver/gator_annotate_kernel.c | 90 -- drivers/gator/driver/gator_backtrace.c | 116 --- drivers/gator/driver/gator_cookies.c | 403 -------- drivers/gator/driver/gator_ebs.c | 192 ---- drivers/gator/driver/gator_events.sh | 19 - drivers/gator/driver/gator_events_armv6.c | 244 ----- drivers/gator/driver/gator_events_armv7.c | 320 ------ drivers/gator/driver/gator_events_block.c | 171 ---- drivers/gator/driver/gator_events_irq.c | 195 ---- drivers/gator/driver/gator_events_l2c-310.c | 179 ---- drivers/gator/driver/gator_events_mali.c | 611 ------------ drivers/gator/driver/gator_events_meminfo.c | 225 ----- drivers/gator/driver/gator_events_mmaped.c | 198 ---- drivers/gator/driver/gator_events_net.c | 144 --- drivers/gator/driver/gator_events_perf_pmu.c | 296 ------ drivers/gator/driver/gator_events_power.c | 178 ---- drivers/gator/driver/gator_events_sched.c | 114 --- drivers/gator/driver/gator_events_scorpion.c | 678 ------------- drivers/gator/driver/gator_fs.c | 284 ------ drivers/gator/driver/gator_hrtimer_gator.c | 76 -- drivers/gator/driver/gator_hrtimer_perf.c | 113 --- drivers/gator/driver/gator_main.c | 1109 --------------------- drivers/gator/driver/gator_pack.c | 262 ----- drivers/gator/driver/gator_trace_gpu.c | 250 ----- drivers/gator/driver/gator_trace_gpu.h | 79 -- drivers/gator/driver/gator_trace_sched.c | 269 ----- 83 files changed, 11927 deletions(-) delete mode 100644 drivers/gator/daemon/Android.mk delete mode 100644 drivers/gator/daemon/CapturedXML.cpp delete mode 100644 drivers/gator/daemon/CapturedXML.h delete mode 100644 drivers/gator/daemon/Child.cpp delete mode 100644 drivers/gator/daemon/Child.h delete mode 100644 drivers/gator/daemon/Collector.cpp delete mode 100644 drivers/gator/daemon/Collector.h delete mode 100644 drivers/gator/daemon/ConfigurationXML.cpp delete mode 100644 drivers/gator/daemon/ConfigurationXML.h delete mode 100644 drivers/gator/daemon/Fifo.cpp delete mode 100644 drivers/gator/daemon/Fifo.h delete mode 100644 drivers/gator/daemon/LocalCapture.cpp delete mode 100644 drivers/gator/daemon/LocalCapture.h delete mode 100644 drivers/gator/daemon/Logging.cpp delete mode 100644 drivers/gator/daemon/Logging.h delete mode 100644 drivers/gator/daemon/Makefile delete mode 100644 drivers/gator/daemon/OlySocket.cpp delete mode 100644 drivers/gator/daemon/OlySocket.h delete mode 100644 drivers/gator/daemon/OlyUtility.cpp delete mode 100644 drivers/gator/daemon/OlyUtility.h delete mode 100644 drivers/gator/daemon/RequestXML.cpp delete mode 100644 drivers/gator/daemon/RequestXML.h delete mode 100644 drivers/gator/daemon/Sender.cpp delete mode 100644 drivers/gator/daemon/Sender.h delete mode 100644 drivers/gator/daemon/SessionData.cpp delete mode 100644 drivers/gator/daemon/SessionData.h delete mode 100644 drivers/gator/daemon/SessionXML.cpp delete mode 100644 drivers/gator/daemon/SessionXML.h delete mode 100644 drivers/gator/daemon/StreamlineSetup.cpp delete mode 100644 drivers/gator/daemon/StreamlineSetup.h delete mode 100644 drivers/gator/daemon/XMLOut.cpp delete mode 100644 drivers/gator/daemon/XMLOut.h delete mode 100644 drivers/gator/daemon/XMLReader.cpp delete mode 100644 drivers/gator/daemon/XMLReader.h delete mode 100644 drivers/gator/daemon/configuration.xml delete mode 100644 drivers/gator/daemon/events-ARM11.xml delete mode 100644 drivers/gator/daemon/events-ARM11MPCore.xml delete mode 100644 drivers/gator/daemon/events-Cortex-A15.xml delete mode 100644 drivers/gator/daemon/events-Cortex-A5.xml delete mode 100644 drivers/gator/daemon/events-Cortex-A7.xml delete mode 100644 drivers/gator/daemon/events-Cortex-A8.xml delete mode 100644 drivers/gator/daemon/events-Cortex-A9.xml delete mode 100644 drivers/gator/daemon/events-Krait-architected.xml delete mode 100644 drivers/gator/daemon/events-L2C-310.xml delete mode 100644 drivers/gator/daemon/events-Linux.xml delete mode 100644 drivers/gator/daemon/events-Mali-400.xml delete mode 100644 drivers/gator/daemon/events-Scorpion.xml delete mode 100644 drivers/gator/daemon/events-ScorpionMP.xml delete mode 100644 drivers/gator/daemon/events_footer.xml delete mode 100644 drivers/gator/daemon/events_header.xml delete mode 100644 drivers/gator/daemon/main.cpp delete mode 100644 drivers/gator/driver/Kconfig delete mode 100644 drivers/gator/driver/Makefile delete mode 100644 drivers/gator/driver/gator.h delete mode 100644 drivers/gator/driver/gator_annotate.c delete mode 100644 drivers/gator/driver/gator_annotate_kernel.c delete mode 100644 drivers/gator/driver/gator_backtrace.c delete mode 100644 drivers/gator/driver/gator_cookies.c delete mode 100644 drivers/gator/driver/gator_ebs.c delete mode 100644 drivers/gator/driver/gator_events.sh delete mode 100644 drivers/gator/driver/gator_events_armv6.c delete mode 100644 drivers/gator/driver/gator_events_armv7.c delete mode 100644 drivers/gator/driver/gator_events_block.c delete mode 100644 drivers/gator/driver/gator_events_irq.c delete mode 100644 drivers/gator/driver/gator_events_l2c-310.c delete mode 100644 drivers/gator/driver/gator_events_mali.c delete mode 100644 drivers/gator/driver/gator_events_meminfo.c delete mode 100644 drivers/gator/driver/gator_events_mmaped.c delete mode 100644 drivers/gator/driver/gator_events_net.c delete mode 100644 drivers/gator/driver/gator_events_perf_pmu.c delete mode 100644 drivers/gator/driver/gator_events_power.c delete mode 100644 drivers/gator/driver/gator_events_sched.c delete mode 100644 drivers/gator/driver/gator_events_scorpion.c delete mode 100644 drivers/gator/driver/gator_fs.c delete mode 100644 drivers/gator/driver/gator_hrtimer_gator.c delete mode 100644 drivers/gator/driver/gator_hrtimer_perf.c delete mode 100644 drivers/gator/driver/gator_main.c delete mode 100644 drivers/gator/driver/gator_pack.c delete mode 100644 drivers/gator/driver/gator_trace_gpu.c delete mode 100644 drivers/gator/driver/gator_trace_gpu.h delete mode 100644 drivers/gator/driver/gator_trace_sched.c diff --git a/drivers/Kconfig b/drivers/Kconfig index 54b409b4312..2101dea3534 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -142,7 +142,5 @@ source "drivers/devfreq/Kconfig" source "drivers/modem/Kconfig" -source "drivers/gator/driver/Kconfig" - endmenu diff --git a/drivers/Makefile b/drivers/Makefile index ee6cd48a81a..944c0b615e8 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -135,5 +135,3 @@ obj-$(CONFIG_VIRT_DRIVERS) += virt/ obj-$(CONFIG_HYPERV) += hv/ obj-$(CONFIG_PM_DEVFREQ) += devfreq/ - -obj-$(CONFIG_GATOR) += gator/driver/ diff --git a/drivers/gator/daemon/Android.mk b/drivers/gator/daemon/Android.mk deleted file mode 100644 index 14aeda2d114..00000000000 --- a/drivers/gator/daemon/Android.mk +++ /dev/null @@ -1,34 +0,0 @@ -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) - -LOCAL_CFLAGS += -Wall -O3 -ftree-vectorize - -LOCAL_SRC_FILES:= \ - CapturedXML.cpp \ - Child.cpp \ - Collector.cpp \ - ConfigurationXML.cpp \ - Fifo.cpp \ - LocalCapture.cpp \ - Logging.cpp \ - main.cpp \ - OlySocket.cpp \ - OlyUtility.cpp \ - RequestXML.cpp \ - Sender.cpp \ - SessionData.cpp \ - SessionXML.cpp \ - StreamlineSetup.cpp \ - XMLOut.cpp \ - XMLReader.cpp - -LOCAL_C_INCLUDES := $(LOCAL_PATH) - -LOCAL_MODULE:= gatord -LOCAL_MODULE_TAGS:= optional - -LOCAL_LDLIBS := -lz -llog - -include $(BUILD_EXECUTABLE) diff --git a/drivers/gator/daemon/CapturedXML.cpp b/drivers/gator/daemon/CapturedXML.cpp deleted file mode 100644 index 51076dd4871..00000000000 --- a/drivers/gator/daemon/CapturedXML.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/** - * 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 -#include -#include -#include "SessionData.h" -#include "CapturedXML.h" -#include "Logging.h" -#include "OlyUtility.h" - -extern void handleException(); - -CapturedXML::CapturedXML() { -} - -CapturedXML::~CapturedXML() { -} - -const char* CapturedXML::getXML() { - bool perfCounters = false; - int x; - - clearXmlString(); - xmlHeader(); - - for (x=0; xmPerfCounterEnabled[x]) { - perfCounters = true; - break; - } - } - - startElement("captured"); - attributeInt("version", 1); - attributeInt("protocol", PROTOCOL_VERSION); - if (gSessionData->mBytes > 0) { // Send the following only after the capture is complete - if (time(NULL) > 1267000000) { // If the time is reasonable (after Feb 23, 2010) - attributeUInt("created", time(NULL)); // Valid until the year 2038 - } - attributeUInt("bytes", gSessionData->mBytes); - } - startElement("target"); - attributeString("name", gSessionData->mCoreName); - attributeInt("sample_rate", gSessionData->mSampleRate); - attributeInt("cores", gSessionData->mCores); - endElement("target"); - if (perfCounters) { - startElement("counters"); - for (x = 0; x < MAX_PERFORMANCE_COUNTERS; x++) { - if (gSessionData->mPerfCounterEnabled[x]) { - startElement("counter"); - attributeString("title", gSessionData->mPerfCounterTitle[x]); - attributeString("name", gSessionData->mPerfCounterName[x]); - attributeHex8("color", gSessionData->mPerfCounterColor[x]); - attributeHex8("key", gSessionData->mPerfCounterKey[x]); - attributeString("type", gSessionData->mPerfCounterType[x]); - attributeHex8("event", gSessionData->mPerfCounterEvent[x]); - if (gSessionData->mPerfCounterPerCPU[x]) { - attributeBool("per_cpu", true); - } - if (strlen(gSessionData->mPerfCounterOperation[x]) > 0) { - attributeString("operation", gSessionData->mPerfCounterOperation[x]); - } - if (gSessionData->mPerfCounterCount[x] > 0) { - attributeInt("count", gSessionData->mPerfCounterCount[x]); - } - attributeString("description", gSessionData->mPerfCounterDescription[x]); - endElement("counter"); - } - } - endElement("counters"); - } - endElement("captured"); - return getXmlString(); -} - -void CapturedXML::write(char* path) { - char* file = (char*)malloc(PATH_MAX); - - // Set full path - snprintf(file, PATH_MAX, "%s/captured.xml", path); - - // Write the file - const char* xml = getXML(); - if (util->writeToDisk(file, xml) < 0) { - logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", file); - handleException(); - } - - free(file); -} diff --git a/drivers/gator/daemon/CapturedXML.h b/drivers/gator/daemon/CapturedXML.h deleted file mode 100644 index d37c59e37ac..00000000000 --- a/drivers/gator/daemon/CapturedXML.h +++ /dev/null @@ -1,23 +0,0 @@ -/** - - * 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. - */ - -#ifndef __CAPTURED_XML_H__ -#define __CAPTURED_XML_H__ - -#include "XMLOut.h" - -class CapturedXML : XMLOut { -public: - CapturedXML(); - ~CapturedXML(); - const char* getXML(); - void write(char* path); -}; - -#endif //__CAPTURED_XML_H__ diff --git a/drivers/gator/daemon/Child.cpp b/drivers/gator/daemon/Child.cpp deleted file mode 100644 index ddf105b8d31..00000000000 --- a/drivers/gator/daemon/Child.cpp +++ /dev/null @@ -1,304 +0,0 @@ -/** - * 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 -#include -#include -#include -#include -#include -#include -#include "Logging.h" -#include "CapturedXML.h" -#include "SessionData.h" -#include "Child.h" -#include "LocalCapture.h" -#include "Collector.h" -#include "Sender.h" -#include "OlyUtility.h" -#include "StreamlineSetup.h" -#include "ConfigurationXML.h" - -static sem_t haltPipeline, senderThreadStarted, startProfile; // Shared by Child and spawned threads -static Fifo* collectorFifo = NULL; // Shared by Child.cpp and spawned threads -static Sender* sender = NULL; // Shared by Child.cpp and spawned threads -Collector* collector = NULL; -Child* child = NULL; // shared by Child.cpp and main.cpp - -extern void cleanUp(); -void handleException() { - if (child && child->numExceptions++ > 0) { - // it is possible one of the below functions itself can cause an exception, thus allow only one exception - logg->logMessage("Received multiple exceptions, terminating the child"); - exit(1); - } - fprintf(stderr, "%s", logg->getLastError()); - - if (child && child->socket) { - if (sender) { - // send the error, regardless of the command sent by Streamline - sender->writeData(logg->getLastError(), strlen(logg->getLastError()), RESPONSE_ERROR); - - // cannot close the socket before Streamline issues the command, so wait for the command before exiting - if (gSessionData->mWaitingOnCommand) { - char discard; - child->socket->receiveNBytes(&discard, 1); - } - - // this indirectly calls close socket which will ensure the data has been sent - delete sender; - } - } - - if (gSessionData->mLocalCapture) - cleanUp(); - - exit(1); -} - -// CTRL C Signal Handler for child process -void child_handler(int signum) { - static bool beenHere = false; - if (beenHere == true) { - logg->logMessage("Gator is being forced to shut down."); - exit(1); - } - beenHere = true; - logg->logMessage("Gator is shutting down."); - if (signum == SIGALRM || !collector) { - exit(1); - } else { - child->endSession(); - alarm(5); // Safety net in case endSession does not complete within 5 seconds - } -} - -void* durationThread(void* pVoid) { - prctl(PR_SET_NAME, (unsigned int)&"gatord-duration", 0, 0, 0); - sem_wait(&startProfile); - if (gSessionData->mSessionIsActive) { - // Time out after duration seconds - // Add a second for host-side filtering - sleep(gSessionData->mDuration + 1); - if (gSessionData->mSessionIsActive) { - logg->logMessage("Duration expired."); - child->endSession(); - } - } - logg->logMessage("Exit duration thread"); - return 0; -} - -void* stopThread(void* pVoid) { - int length; - char type; - OlySocket* socket = child->socket; - - prctl(PR_SET_NAME, (unsigned int)&"gatord-stopper", 0, 0, 0); - while (gSessionData->mSessionIsActive) { - // This thread will stall until the APC_STOP or PING command is received over the socket or the socket is disconnected - if (socket->receiveNBytes(&type, sizeof(type)) > 0) { - if ((type != COMMAND_APC_STOP) && (type != COMMAND_PING)) { - logg->logMessage("INVESTIGATE: Received unknown command type %d", type); - } else { - // verify a length of zero - if (socket->receiveNBytes((char*)&length, sizeof(length)) < 0) { - break; - } - - if (length == 0) { - if (type == COMMAND_APC_STOP) { - logg->logMessage("Stop command received."); - child->endSession(); - } else { - // Ping is used to make sure gator is alive and requires an ACK as the response - logg->logMessage("Ping command received."); - sender->writeData(NULL, 0, RESPONSE_ACK); - } - } else { - logg->logMessage("INVESTIGATE: Received stop command but with length = %d", length); - } - } - } - } - - logg->logMessage("Exit stop thread"); - return 0; -} - -void* senderThread(void* pVoid) { - int length; - char* data; - - sem_post(&senderThreadStarted); - prctl(PR_SET_NAME, (unsigned int)&"gatord-sender", 0, 0, 0); - sem_wait(&haltPipeline); - - do { - data = collectorFifo->read(&length); - sender->writeData(data, length, RESPONSE_APC_DATA); - } while (length > 0); - logg->logMessage("Exit sender thread"); - return 0; -} - -Child::Child(char* path) { - initialization(); - sessionXMLPath = path; - gSessionData->mLocalCapture = true; -} - -Child::Child(OlySocket* sock, int conn) { - initialization(); - socket = sock; - numConnections = conn; -} - -Child::~Child() { -} - -void Child::initialization() { - // Set up different handlers for signals - gSessionData->mSessionIsActive = true; - signal(SIGINT, child_handler); - signal(SIGTERM, child_handler); - signal(SIGABRT, child_handler); - signal(SIGALRM, child_handler); - socket = NULL; - numExceptions = 0; - numConnections = 0; - sessionXMLPath = 0; - - // Initialize semaphores - sem_init(&senderThreadStarted, 0, 0); - sem_init(&startProfile, 0, 0); -} - -void Child::endSession() { - gSessionData->mSessionIsActive = false; - collector->stop(); - sem_post(&haltPipeline); -} - -void Child::run() { - char* collectBuffer; - int bytesCollected = 0; - LocalCapture* localCapture = NULL; - - prctl(PR_SET_NAME, (unsigned int)&"gatord-child", 0, 0, 0); - - // Instantiate the Sender - must be done first, after which error messages can be sent - sender = new Sender(socket); - - if (numConnections > 1) { - logg->logError(__FILE__, __LINE__, "Session already in progress"); - handleException(); - } - - // Populate gSessionData with the configuration - new ConfigurationXML(); - - // Set up the driver; must be done after gSessionData->mPerfCounterType[] is populated - collector = new Collector(); - - // Start up and parse session xml - if (socket) { - // Respond to Streamline requests - StreamlineSetup ss(socket); - } else { - xmlString = util->readFromDisk(sessionXMLPath); - if (xmlString == 0) { - logg->logError(__FILE__, __LINE__, "Unable to read session xml file: %s", sessionXMLPath); - handleException(); - } - gSessionData->parseSessionXML(xmlString); - localCapture = new LocalCapture(); - localCapture->createAPCDirectory(gSessionData->target_path, gSessionData->title); - localCapture->copyImages(gSessionData->images); - localCapture->write(xmlString); - sender->createDataFile(gSessionData->apcDir); - delete xmlString; - } - - // Write configuration into the driver - collector->setupPerfCounters(); - - // Create user-space buffers - int fifoBufferSize = collector->getBufferSize(); - int numCollectorBuffers = (gSessionData->mTotalBufferSize * 1024 * 1024 + fifoBufferSize - 1) / fifoBufferSize; - numCollectorBuffers = (numCollectorBuffers < 4) ? 4 : numCollectorBuffers; - logg->logMessage("Created %d %d-byte collector buffers", numCollectorBuffers, fifoBufferSize); - collectorFifo = new Fifo(numCollectorBuffers, fifoBufferSize); - - // Get the initial pointer to the collect buffer - collectBuffer = collectorFifo->start(); - - // Sender thread shall be halted until it is signaled for one shot mode - sem_init(&haltPipeline, 0, gSessionData->mOneShot ? 0 : 2); - - // Create the duration, stop, and sender threads - bool thread_creation_success = true; - if (gSessionData->mDuration > 0 && pthread_create(&durationThreadID, NULL, durationThread, NULL)) - thread_creation_success = false; - else if (socket && pthread_create(&stopThreadID, NULL, stopThread, NULL)) - thread_creation_success = false; - else if (pthread_create(&senderThreadID, NULL, senderThread, NULL)) - thread_creation_success = false; - if (!thread_creation_success) { - logg->logError(__FILE__, __LINE__, "Failed to create gator threads"); - handleException(); - } - - // Wait until thread has started - sem_wait(&senderThreadStarted); - - // Start profiling - logg->logMessage("********** Profiling started **********"); - collector->start(); - sem_post(&startProfile); - - // Collect Data - do { - // This command will stall until data is received from the driver - bytesCollected = collector->collect(collectBuffer); - - // In one shot mode, stop collection once all the buffers are filled - if (gSessionData->mOneShot && gSessionData->mSessionIsActive) { - // Depth minus 1 because write() has not yet been called - if ((bytesCollected == -1) || (collectorFifo->numWriteToReadBuffersFilled() == collectorFifo->depth() - 1)) { - logg->logMessage("One shot"); - endSession(); - } - } - collectBuffer = collectorFifo->write(bytesCollected); - } while (bytesCollected > 0); - logg->logMessage("Exit collect data loop"); - - // Wait for the other threads to exit - pthread_join(senderThreadID, NULL); - - // Shutting down the connection should break the stop thread which is stalling on the socket recv() function - if (socket) { - logg->logMessage("Waiting on stop thread"); - socket->shutdownConnection(); - pthread_join(stopThreadID, NULL); - } - - // Write the captured xml file - if (gSessionData->mLocalCapture) { - CapturedXML capturedXML; - capturedXML.write(gSessionData->apcDir); - } - - logg->logMessage("Profiling ended."); - - delete collectorFifo; - delete sender; - delete collector; - delete localCapture; -} diff --git a/drivers/gator/daemon/Child.h b/drivers/gator/daemon/Child.h deleted file mode 100644 index eee5ac70f9e..00000000000 --- a/drivers/gator/daemon/Child.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * 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. - */ - -#ifndef __CHILD_H__ -#define __CHILD_H__ - -#include -#include "Fifo.h" -#include "OlySocket.h" - -class Child { -public: - Child(char* sessionXMLPath); - Child(OlySocket* sock, int numConnections); - ~Child(); - void run(); - OlySocket *socket; - void endSession(); - int numExceptions; -private: - char* xmlString; - char* sessionXMLPath; - int numConnections; - time_t timeStart; - pthread_t durationThreadID, stopThreadID, senderThreadID; - - void initialization(); -}; - -#endif //__CHILD_H__ diff --git a/drivers/gator/daemon/Collector.cpp b/drivers/gator/daemon/Collector.cpp deleted file mode 100644 index 7a41198e5cb..00000000000 --- a/drivers/gator/daemon/Collector.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/** - * 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 -#include -#include -#include -#include -#include -#include -#include "Collector.h" -#include "SessionData.h" -#include "Logging.h" - -extern void handleException(); - -// Driver initialization independent of session settings -Collector::Collector() { - char text[sizeof(gSessionData->mPerfCounterType[0]) + 20]; // sufficiently large to hold all events// - - bufferFD = 0; - - checkVersion(); - - int enable = -1; - if (readIntDriver("enable", &enable) != 0 || enable != 0) { - logg->logError(__FILE__, __LINE__, "Driver already enabled, possibly a session is already in progress."); - handleException(); - } - - readIntDriver("cpu_cores", &gSessionData->mCores); - if (gSessionData->mCores == 0) { - gSessionData->mCores = 1; - } - - bufferSize = 512 * 1024; - if (writeReadDriver("buffer_size", &bufferSize) || bufferSize <= 0) { - logg->logError(__FILE__, __LINE__, "Unable to set the driver buffer size"); - handleException(); - } - - getCoreName(); - - enablePerfCounters(); - - // Read unchanging keys from driver which are created at insmod'ing of gator.ko - for (int i = 0; i < MAX_PERFORMANCE_COUNTERS; i++) { - if (gSessionData->mPerfCounterEnabled[i]) { - snprintf(text, sizeof(text), "events/%s/key", gSessionData->mPerfCounterType[i]); - readIntDriver(text, &gSessionData->mPerfCounterKey[i]); - } - } -} - -Collector::~Collector() { - // Write zero for safety, as a zero should have already been written - writeDriver("enable", "0"); - - // Calls event_buffer_release in the driver - if (bufferFD) { - close(bufferFD); - } -} - -void Collector::enablePerfCounters() { - char text[sizeof(gSessionData->mPerfCounterType[0]) + 30]; // sufficiently large to hold all /dev/gator/events//enabled - for (int i=0; imPerfCounterEnabled[i]) { - continue; - } - snprintf(text, sizeof(text), "events/%s/enabled", gSessionData->mPerfCounterType[i]); - if (writeReadDriver(text, &gSessionData->mPerfCounterEnabled[i])) { - // Disable those events that don't exist on this hardware platform even though they exist in configuration.xml - gSessionData->mPerfCounterEnabled[i] = 0; - continue; - } - } -} - -void Collector::setupPerfCounters() { - char base[sizeof(gSessionData->mPerfCounterType[0]) + 10]; // sufficiently large to hold all events/ - char text[sizeof(gSessionData->mPerfCounterType[0]) + 20]; // sufficiently large to hold all events// - - for (int i=0; imPerfCounterEnabled[i]) { - continue; - } - snprintf(base, sizeof(base), "events/%s", gSessionData->mPerfCounterType[i]); - snprintf(text, sizeof(text), "%s/event", base); - writeDriver(text, gSessionData->mPerfCounterEvent[i]); - if (gSessionData->mPerfCounterEBSCapable[i]) { - snprintf(text, sizeof(text), "%s/count", base); - if (access(resolvePath(text), F_OK) == 0) { - if (writeReadDriver(text, &gSessionData->mPerfCounterCount[i]) && gSessionData->mPerfCounterCount[i] > 0) { - logg->logError(__FILE__, __LINE__, "Cannot enable EBS for %s with a count of %d\n", gSessionData->mPerfCounterName[i], gSessionData->mPerfCounterCount[i]); - handleException(); - } - } else if (gSessionData->mPerfCounterCount[i] > 0) { - logg->logError(__FILE__, __LINE__, "Event Based Sampling is only supported with kernel versions 3.0.0 and higher with CONFIG_PERF_EVENTS=y, and CONFIG_HW_PERF_EVENTS=y\n"); - handleException(); - } - } - } -} - -void Collector::checkVersion() { - int driver_version = 0; - - if (readIntDriver("version", &driver_version) == -1) { - logg->logError(__FILE__, __LINE__, "Error reading gator driver version"); - handleException(); - } - - // Verify the driver version matches the daemon version - if (driver_version != PROTOCOL_VERSION) { - if ((driver_version > PROTOCOL_DEV) || (PROTOCOL_VERSION > PROTOCOL_DEV)) { - // One of the mismatched versions is development version - logg->logError(__FILE__, __LINE__, - "DEVELOPMENT BUILD MISMATCH: gator driver version \"%d\" is not in sync with gator daemon version \"%d\".\n" - ">> The following must be synchronized from engineering repository:\n" - ">> * gator driver\n" - ">> * gator daemon\n" - ">> * Streamline", driver_version, PROTOCOL_VERSION); - handleException(); - } else { - // Release version mismatch - logg->logError(__FILE__, __LINE__, - "gator driver version \"%d\" is different than gator daemon version \"%d\".\n" - ">> Please upgrade the driver and daemon to the latest versions.", driver_version, PROTOCOL_VERSION); - handleException(); - } - } -} - -void Collector::start() { - // Set the maximum backtrace depth - if (writeReadDriver("backtrace_depth", &gSessionData->mBacktraceDepth)) { - logg->logError(__FILE__, __LINE__, "Unable to set the driver backtrace depth"); - handleException(); - } - - // open the buffer which calls userspace_buffer_open() in the driver - bufferFD = open(resolvePath("buffer"), O_RDONLY); - if (bufferFD < 0) { - logg->logError(__FILE__, __LINE__, "The gator driver did not set up properly. Please view the linux console or dmesg log for more information on the failure."); - handleException(); - } - - // set the tick rate of the profiling timer - if (writeReadDriver("tick", &gSessionData->mSampleRate) != 0) { - logg->logError(__FILE__, __LINE__, "Unable to set the driver tick"); - handleException(); - } - - // notify the kernel of the streaming mode, currently used for network stats - int streaming = (int)!gSessionData->mOneShot; - if (writeReadDriver("streaming", &streaming) != 0) { - logg->logError(__FILE__, __LINE__, "Unable to set streaming"); - handleException(); - } - - logg->logMessage("Start the driver"); - - // This command makes the driver start profiling by calling gator_op_start() in the driver - if (writeDriver("enable", "1") != 0) { - logg->logError(__FILE__, __LINE__, "The gator driver did not start properly. Please view the linux console or dmesg log for more information on the failure."); - handleException(); - } - - lseek(bufferFD, 0, SEEK_SET); -} - -// These commands should cause the read() function in collect() to return -void Collector::stop() { - // This will stop the driver from profiling - if (writeDriver("enable", "0") != 0) { - logg->logMessage("Stopping kernel failed"); - } -} - -int Collector::collect(char* buffer) { - // Calls event_buffer_read in the driver - int bytesRead = read(bufferFD, buffer, bufferSize); - - // If read() returned due to an interrupt signal, re-read to obtain the last bit of collected data - if (bytesRead == -1 && errno == EINTR) { - bytesRead = read(bufferFD, buffer, bufferSize); - } - - logg->logMessage("Driver read of %d bytes", bytesRead); - - return bytesRead; -} - -void Collector::getCoreName() { - char temp[256]; // arbitrarily large amount - strcpy(gSessionData->mCoreName, "unknown"); - - FILE* f = fopen("/proc/cpuinfo", "r"); - if (f == NULL) { - logg->logMessage("Error opening /proc/cpuinfo\n" - "The core name in the captured xml file will be 'unknown'."); - return; - } - - while (fgets(temp, sizeof(temp), f)) { - if (strlen(temp) > 0) - temp[strlen(temp) - 1] = 0; // Replace the line feed with a null - - if (strstr(temp, "Hardware") != 0) { - char* position = strchr(temp, ':'); - if (position == NULL || (unsigned int)(position - temp) + 2 >= strlen(temp)) { - logg->logMessage("Unknown format of /proc/cpuinfo\n" - "The core name in the captured xml file will be 'unknown'."); - return; - } - strncpy(gSessionData->mCoreName, (char *)((int)position + 2), sizeof(gSessionData->mCoreName)); - gSessionData->mCoreName[sizeof(gSessionData->mCoreName) - 1] = 0; // strncpy does not guarantee a null-terminated string - fclose(f); - return; - } - } - - logg->logMessage("Could not determine core name from /proc/cpuinfo\n" - "The core name in the captured xml file will be 'unknown'."); - fclose(f); -} - -char* Collector::resolvePath(const char* file) { - static char fullpath[100]; // Sufficiently large to hold any path within /dev/gator - snprintf(fullpath, sizeof(fullpath), "/dev/gator/%s", file); - return fullpath; -} - -int Collector::readIntDriver(const char* path, int* value) { - char* fullpath = resolvePath(path); - FILE* file = fopen(fullpath, "r"); - if (file == NULL) { - return -1; - } - if (fscanf(file, "%u", value) != 1) { - fclose(file); - logg->logMessage("Invalid value in file %s", fullpath); - return -1; - } - fclose(file); - return 0; -} - -int Collector::writeDriver(const char* path, int value) { - char data[40]; // Sufficiently large to hold any integer - snprintf(data, sizeof(data), "%d", value); - return writeDriver(path, data); -} - -int Collector::writeDriver(const char* path, const char* data) { - char* fullpath = resolvePath(path); - int fd = open(fullpath, O_WRONLY); - if (fd < 0) { - return -1; - } - if (write(fd, data, strlen(data)) < 0) { - close(fd); - logg->logMessage("Opened but could not write to %s", fullpath); - return -1; - } - close(fd); - return 0; -} - -int Collector::writeReadDriver(const char* path, int* value) { - if (writeDriver(path, *value) || readIntDriver(path, value)) { - return -1; - } - return 0; -} diff --git a/drivers/gator/daemon/Collector.h b/drivers/gator/daemon/Collector.h deleted file mode 100644 index 6c80725ad94..00000000000 --- a/drivers/gator/daemon/Collector.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * 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. - */ - -#ifndef __COLLECTOR_H__ -#define __COLLECTOR_H__ - -#include - -class Collector { -public: - Collector(); - ~Collector(); - void start(); - void stop(); - int collect(char* buffer); - void enablePerfCounters(); - void setupPerfCounters(); - int getBufferSize() {return bufferSize;} -private: - int bufferSize; - int bufferFD; - char * buffer; - - void checkVersion(); - void getCoreName(); - - char* resolvePath(const char* file); - int readIntDriver(const char* path, int* value); - int writeDriver(const char* path, int value); - int writeDriver(const char* path, const char* data); - int writeReadDriver(const char* path, int* value); -}; - -#endif //__COLLECTOR_H__ diff --git a/drivers/gator/daemon/ConfigurationXML.cpp b/drivers/gator/daemon/ConfigurationXML.cpp deleted file mode 100644 index e1bec0fd4fa..00000000000 --- a/drivers/gator/daemon/ConfigurationXML.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/** - * 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 -#include -#include -#include "ConfigurationXML.h" -#include "Logging.h" -#include "OlyUtility.h" -#include "SessionData.h" - -extern void handleException(); - -static const char* ATTR_COUNTER = "counter"; -static const char* ATTR_VERSION = "version"; -static const char* ATTR_TITLE = "title"; -static const char* ATTR_NAME = "name"; -static const char* ATTR_EVENT = "event"; -static const char* ATTR_COLOR = "color"; -static const char* ATTR_COUNT = "count"; -static const char* ATTR_OPERATION = "operation"; -static const char* ATTR_PER_CPU = "per_cpu"; -static const char* ATTR_DESCRIPTION = "description"; -static const char* ATTR_EBS = "event_based_sampling"; - -ConfigurationXML::ConfigurationXML() { -#include "configuration_xml.h" // defines and initializes char configuration_xml[] and int configuration_xml_len - index = 0; - char* path = (char *)malloc(PATH_MAX); - - if (gSessionData->configurationXMLPath) { - strncpy(path, gSessionData->configurationXMLPath, PATH_MAX); - } else { - if (util->getApplicationFullPath(path, PATH_MAX) != 0) { - logg->logMessage("Unable to determine the full path of gatord, the cwd will be used"); - } - strncat(path, "configuration.xml", PATH_MAX - strlen(path) - 1); - } - mConfigurationXML = util->readFromDisk(path); - - if (mConfigurationXML == NULL) { - logg->logMessage("Unable to locate configuration.xml, using default in binary"); - // null-terminate configuration_xml - mConfigurationXML = (char*)malloc(configuration_xml_len + 1); - memcpy(mConfigurationXML, (const void*)configuration_xml, configuration_xml_len); - mConfigurationXML[configuration_xml_len] = 0; - } - - // disable all counters prior to parsing the configuration xml - for (int i = 0; i < MAX_PERFORMANCE_COUNTERS; i++) { - gSessionData->mPerfCounterEnabled[i] = 0; - } - - int ret = parse(mConfigurationXML); - if (ret == 1) { - // remove configuration.xml on disk to use the default - if (remove(path) != 0) { - logg->logError(__FILE__, __LINE__, "Invalid configuration.xml file detected and unable to delete it. To resolve, delete configuration.xml on disk"); - handleException(); - } - } else if (ret < 0 || isValid() == false) { - logg->logError(__FILE__, __LINE__, "Parsing of the configuration.xml file failed. Please verify configuration.xml on the target filesystem is valid or delete it to use the default."); - handleException(); - } - - free(path); -} - -ConfigurationXML::~ConfigurationXML() { - if (mConfigurationXML) { - free((void*)mConfigurationXML); - } -} - -int ConfigurationXML::parse(const char* configurationXML) { - int ret = 0; - XMLReader reader(configurationXML); - char * tag = reader.nextTag(); - while(tag != 0 && ret == 0) { - if (strcmp(tag, "configurations") == 0) { - ret = configurationsTag(&reader); - } else if (strcmp(tag, "configuration") == 0) { - ret = configurationTag(&reader); - } - tag = reader.nextTag(); - } - - return ret; -} - -bool ConfigurationXML::isValid(void) { - for (int i = 0; i < MAX_PERFORMANCE_COUNTERS; i++) { - if (gSessionData->mPerfCounterEnabled[i]) { - if (strcmp(gSessionData->mPerfCounterType[i], "") == 0 || - strcmp(gSessionData->mPerfCounterTitle[i], "") == 0 || - strcmp(gSessionData->mPerfCounterName[i], "") == 0) { - logg->logMessage("Invalid required attribute\n counter=\"%s\"\n title=\"%s\"\n name=\"%s\"\n event=%d\n", gSessionData->mPerfCounterType[i], gSessionData->mPerfCounterTitle[i], gSessionData->mPerfCounterName[i], gSessionData->mPerfCounterEvent[i]); - return false; // failure - } - - // iterate through the remaining enabled performance counters - for (int j = i + 1; j < MAX_PERFORMANCE_COUNTERS; j++) { - if (gSessionData->mPerfCounterEnabled[j]) { - // check if the type or device are the same - if (strcmp(gSessionData->mPerfCounterType[i], gSessionData->mPerfCounterType[j]) == 0) { - logg->logMessage("Duplicate performance counter type: %s", gSessionData->mPerfCounterType[i]); - return false; // failure - } - } - } - } - } - - return true; // success -} - -#define CONFIGURATION_VERSION 1 -int ConfigurationXML::configurationsTag(XMLReader *in) { - int version = in->getAttributeAsInteger(ATTR_VERSION, 0); - if (version != CONFIGURATION_VERSION) { - logg->logMessage("Incompatible configuration.xml version (%d) detected. The version needs to be %d.", version, CONFIGURATION_VERSION); - return 1; // version issue - } - return 0; -} - -int ConfigurationXML::configurationTag(XMLReader* in) { - // handle all other performance counters - if (index >= MAX_PERFORMANCE_COUNTERS) { - logg->logMessage("Invalid performance counter index: %d", index); - return -1; // failure - } - - // read attributes - in->getAttribute(ATTR_COUNTER, gSessionData->mPerfCounterType[index], sizeof(gSessionData->mPerfCounterType[index]), ""); - in->getAttribute(ATTR_TITLE, gSessionData->mPerfCounterTitle[index], sizeof(gSessionData->mPerfCounterTitle[index]), ""); - in->getAttribute(ATTR_NAME, gSessionData->mPerfCounterName[index], sizeof(gSessionData->mPerfCounterName[index]), ""); - in->getAttribute(ATTR_DESCRIPTION, gSessionData->mPerfCounterDescription[index], sizeof(gSessionData->mPerfCounterDescription[index]), ""); - gSessionData->mPerfCounterEvent[index] = in->getAttributeAsInteger(ATTR_EVENT, 0); - gSessionData->mPerfCounterCount[index] = in->getAttributeAsInteger(ATTR_COUNT, 0); - gSessionData->mPerfCounterColor[index] = in->getAttributeAsInteger(ATTR_COLOR, 0); - gSessionData->mPerfCounterPerCPU[index] = in->getAttributeAsBoolean(ATTR_PER_CPU, false); - gSessionData->mPerfCounterEBSCapable[index] = in->getAttributeAsBoolean(ATTR_EBS, false); - in->getAttribute(ATTR_OPERATION, gSessionData->mPerfCounterOperation[index], sizeof(gSessionData->mPerfCounterOperation[index]), ""); - gSessionData->mPerfCounterEnabled[index] = true; - - // update counter index - index++; - - return 0; // success -} diff --git a/drivers/gator/daemon/ConfigurationXML.h b/drivers/gator/daemon/ConfigurationXML.h deleted file mode 100644 index 047c4b07705..00000000000 --- a/drivers/gator/daemon/ConfigurationXML.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - * 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. - */ - -#ifndef COUNTERS_H -#define COUNTERS_H - -#include "XMLReader.h" - -class ConfigurationXML { -public: - ConfigurationXML(); - ~ConfigurationXML(); - const char* getConfigurationXML() {return mConfigurationXML;} -private: - char* mConfigurationXML; - - int parse(const char* xmlFile); - bool isValid(void); - int configurationsTag(XMLReader *in); - int configurationTag(XMLReader* in); - int index; -}; - -#endif // COUNTERS_H diff --git a/drivers/gator/daemon/Fifo.cpp b/drivers/gator/daemon/Fifo.cpp deleted file mode 100644 index 1456183b0f0..00000000000 --- a/drivers/gator/daemon/Fifo.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/** - * 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 -#include -#include -#include "Fifo.h" -#include "Logging.h" - -extern void handleException(); - -Fifo::Fifo(int numBuffers, int bufferSize) { - int which; - - if (numBuffers > FIFO_BUFFER_LIMIT) { - logg->logError(__FILE__, __LINE__, "Number of fifo buffers exceeds maximum"); - handleException(); - } - mNumBuffers = numBuffers; - mBufferSize = bufferSize; - mWriteCurrent = 0; - mReadCurrent = mNumBuffers - 1; // (n-1) pipelined - - for (which=0; whichlogError(__FILE__, __LINE__, "sem_init(%d) failed", which); - handleException(); - } - // page-align allocate buffers - mBuffer[which] = (char*)valloc(bufferSize); - if (mBuffer[which] == NULL) { - logg->logError(__FILE__, __LINE__, "failed to allocate %d bytes", bufferSize); - handleException(); - } - // touch each page to fault it in - for (int i=0; i - -// Number of buffers allowed with large buffer mode -#define FIFO_BUFFER_LIMIT 64 - -class Fifo { -public: - Fifo(int numBuffers, int bufferSize); - ~Fifo(); - int depth(void); - int numReadToWriteBuffersFilled(); - int numWriteToReadBuffersFilled(); - int numReadToWriteBuffersEmpty() {return depth() - numReadToWriteBuffersFilled();} - int numWriteToReadBuffersEmpty() {return depth() - numWriteToReadBuffersFilled();} - char* start(); - char* write(int length); - char* read(int* length); - -private: - int mNumBuffers; - int mBufferSize; - int mWriteCurrent; - int mReadCurrent; - sem_t mReadToWriteSem[FIFO_BUFFER_LIMIT]; - sem_t mWriteToReadSem[FIFO_BUFFER_LIMIT]; - char* mBuffer[FIFO_BUFFER_LIMIT]; - int mLength[FIFO_BUFFER_LIMIT]; -}; - -#endif //__FIFO_H__ diff --git a/drivers/gator/daemon/LocalCapture.cpp b/drivers/gator/daemon/LocalCapture.cpp deleted file mode 100644 index 4a2d6d755e6..00000000000 --- a/drivers/gator/daemon/LocalCapture.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/** - * 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 -#include -#include -#include -#include -#include -#include "LocalCapture.h" -#include "SessionData.h" -#include "Logging.h" -#include "OlyUtility.h" - -extern void handleException(); - -LocalCapture::LocalCapture() {} - -LocalCapture::~LocalCapture() {} - -void LocalCapture::createAPCDirectory(char* target_path, char* name) { - gSessionData->apcDir = createUniqueDirectory(target_path, ".apc", name); - if ((removeDirAndAllContents(gSessionData->apcDir) != 0 || mkdir(gSessionData->apcDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0)) { - logg->logError(__FILE__, __LINE__, "Unable to create directory %s", gSessionData->apcDir); - handleException(); - } -} - -void LocalCapture::write(char* string) { - char* file = (char*)malloc(PATH_MAX); - - // Set full path - snprintf(file, PATH_MAX, "%s/session.xml", gSessionData->apcDir); - - // Write the file - if (util->writeToDisk(file, string) < 0) { - logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", file); - handleException(); - } - - free(file); -} - -char* LocalCapture::createUniqueDirectory(const char* initialPath, const char* ending, char* title) { - int i; - char* output; - char* path = (char*)malloc(PATH_MAX); - - // Ensure the path is an absolute path, i.e. starts with a slash - if (initialPath == 0 || strlen(initialPath) == 0) { - if (getcwd(path, PATH_MAX) == 0) - logg->logMessage("Unable to retrive the current working directory"); - strncat(path, "/@F_@N", PATH_MAX - strlen(path) - 1); - } else if (initialPath[0] != '/') { - if (getcwd(path, PATH_MAX) == 0) - logg->logMessage("Unable to retrive the current working directory"); - strncat(path, "/", PATH_MAX - strlen(path) - 1); - strncat(path, initialPath, PATH_MAX - strlen(path) - 1); - } else { - strncpy(path, initialPath, PATH_MAX); - path[PATH_MAX - 1] = 0; // strncpy does not guarantee a null-terminated string - } - - // Convert to uppercase - replaceAll(path, "@f", "@F", PATH_MAX); - replaceAll(path, "@n", "@N", PATH_MAX); - - // Replace @F with the session xml title - replaceAll(path, "@F", title, PATH_MAX); - - // Add ending if it is not already there - if (strcmp(&path[strlen(path) - strlen(ending)], ending) != 0) { - strncat(path, ending, PATH_MAX - strlen(path) - 1); - } - - // Replace @N with a unique integer - if (strstr(path, "@N")) { - char* tempPath = (char*)malloc(PATH_MAX); - for (i = 1; i < 1000; i++) { - char number[4]; - snprintf(number, sizeof(number), "%03d", i); - strcpy(tempPath, path); - replaceAll(tempPath, "@N", number, PATH_MAX); - struct stat mFileInfo; - if (stat(tempPath, &mFileInfo) != 0) { - // if the direcotry does not exist, break - break; - } - } - - if (i == 1000) { - logg->logError(__FILE__, __LINE__, "Unable to create .apc directory, please delete older directories."); - handleException(); - } - - output = strdup(tempPath); - free(tempPath); - } else { - output = strdup(path); - } - - free(path); - return output; -} - -//Replaces all occurrences of in with provided enough is available -void LocalCapture::replaceAll(char* target, const char* find, const char* replace, unsigned int size) { - char* nextOccurrence; - unsigned int count = 0; - - // Duplicate the original string - char* original = strdup(target); - char* ptr = original; - - // Determine number of s - ptr = strstr(ptr, find); - while (ptr) { - count++; - ptr += strlen(find); - ptr = strstr(ptr, find); - } - - // Is there enough space available - if (strlen(target) + (strlen(replace) - strlen(find)) * count > size - 1) { - free(original); - return; - } - - // Reset - ptr = original; - - nextOccurrence = strstr(ptr, find); - while (nextOccurrence) { - // Move pointers to location of replace - int length = nextOccurrence - ptr; - target += length; - ptr += length; - - // Replace with - memcpy(target, replace, strlen(replace)); - - // Increment over / - target += strlen(replace); - ptr += strlen(find); - - // Copy remainder of ptr - strcpy(target, ptr); - - // Get next occurrence - nextOccurrence = strstr(ptr, find); - } - - free(original); -} - -int LocalCapture::removeDirAndAllContents(char *path) { - int error = 0; - struct stat mFileInfo; - // Does the path exist? - if (stat(path, &mFileInfo) == 0) { - // Is it a directory? - if (mFileInfo.st_mode & S_IFDIR) { - DIR * dir = opendir(path); - dirent* entry = readdir(dir); - while (entry) { - if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { - char* newpath = (char*)malloc(strlen(path) + strlen(entry->d_name) + 2); - sprintf(newpath, "%s/%s", path, entry->d_name); - error = removeDirAndAllContents(newpath); - free(newpath); - if (error) break; - } - entry = readdir(dir); - } - closedir(dir); - if (error == 0) { - error = rmdir(path); - } - } else { - error = remove(path); - } - } - return error; -} - -void LocalCapture::copyImages(ImageLinkList* ptr) { - char* dstfilename = (char*)malloc(PATH_MAX); - - while (ptr) { - strncpy(dstfilename, gSessionData->apcDir, PATH_MAX); - dstfilename[PATH_MAX - 1] = 0; // strncpy does not guarantee a null-terminated string - if (gSessionData->apcDir[strlen(gSessionData->apcDir) - 1] != '/') - strncat(dstfilename, "/", PATH_MAX - strlen(dstfilename) - 1); - strncat(dstfilename, util->getFilePart(ptr->path), PATH_MAX - strlen(dstfilename) - 1); - if (util->copyFile(ptr->path, dstfilename)) - logg->logMessage("copied file %s to %s", ptr->path, dstfilename); - else - logg->logMessage("copy of file %s to %s failed", ptr->path, dstfilename); - - ptr = ptr->next; - } - free(dstfilename); -} diff --git a/drivers/gator/daemon/LocalCapture.h b/drivers/gator/daemon/LocalCapture.h deleted file mode 100644 index 4f5f8186e09..00000000000 --- a/drivers/gator/daemon/LocalCapture.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - * 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. - */ - -#ifndef __LOCAL_CAPTURE_H__ -#define __LOCAL_CAPTURE_H__ - -#include "SessionXML.h" - -class LocalCapture { -public: - LocalCapture(); - ~LocalCapture(); - void write(char *string); - void copyImages(ImageLinkList* ptr); - void createAPCDirectory(char* target_path, char* name); -private: - char* createUniqueDirectory(const char* path, const char* ending, char* title); - void replaceAll(char* target, const char* find, const char* replace, unsigned int size); - int removeDirAndAllContents(char *path); -}; - -#endif //__LOCAL_CAPTURE_H__ diff --git a/drivers/gator/daemon/Logging.cpp b/drivers/gator/daemon/Logging.cpp deleted file mode 100644 index 3e6f8a388a4..00000000000 --- a/drivers/gator/daemon/Logging.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/** - * 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 -#include -#include -#include -#include "OlyUtility.h" - -#ifdef WIN32 -#define MUTEX_INIT() mLoggingMutex = CreateMutex(NULL, false, NULL); -#define MUTEX_LOCK() WaitForSingleObject(mLoggingMutex, 0xFFFFFFFF); -#define MUTEX_UNLOCK() ReleaseMutex(mLoggingMutex); -#define snprintf _snprintf -#else -#include -#define MUTEX_INIT() pthread_mutex_init(&mLoggingMutex, NULL) -#define MUTEX_LOCK() pthread_mutex_lock(&mLoggingMutex) -#define MUTEX_UNLOCK() pthread_mutex_unlock(&mLoggingMutex) -#endif - -#include "Logging.h" - -// Global thread-safe logging -Logging* logg = NULL; - -Logging::Logging(bool debug) { - mDebug = debug; - MUTEX_INIT(); - - strcpy(mErrBuf, "Unknown Error"); - strcpy(mLogBuf, "Unknown Message"); -} - -Logging::~Logging() { -} - -void Logging::logError(const char* file, int line, const char* fmt, ...) { - va_list args; - - MUTEX_LOCK(); - if (mDebug) { - snprintf(mErrBuf, sizeof(mErrBuf), "ERROR[%s:%d]: ", file, line); - } else { - mErrBuf[0] = 0; - } - - va_start(args, fmt); - vsnprintf(mErrBuf + strlen(mErrBuf), sizeof(mErrBuf) - 2 - strlen(mErrBuf), fmt, args); // subtract 2 for \n and \0 - va_end(args); - - if (strlen(mErrBuf) > 0) { - strcat(mErrBuf, "\n"); - } - MUTEX_UNLOCK(); -} - -void Logging::logMessage(const char* fmt, ...) { - if (mDebug) { - va_list args; - - MUTEX_LOCK(); - strcpy(mLogBuf, "INFO: "); - - va_start(args, fmt); - vsnprintf(mLogBuf + strlen(mLogBuf), sizeof(mLogBuf) - 2 - strlen(mLogBuf), fmt, args); // subtract 2 for \n and \0 - va_end(args); - strcat(mLogBuf, "\n"); - - fprintf(stdout, "%s", mLogBuf); - fflush(stdout); - MUTEX_UNLOCK(); - } -} diff --git a/drivers/gator/daemon/Logging.h b/drivers/gator/daemon/Logging.h deleted file mode 100644 index 424796658f7..00000000000 --- a/drivers/gator/daemon/Logging.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * 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. - */ - -#ifndef __LOGGING_H__ -#define __LOGGING_H__ - -#include -#include -#include -#ifdef WIN32 -#include -#else -#include -#endif - -#define DRIVER_ERROR "\n Driver issue:\n >> gator.ko must be built against the current kernel version & configuration\n >> gator.ko should be co-located with gatord in the same directory\n >> OR insmod gator.ko prior to launching gatord" - -class Logging { -public: - Logging(bool debug); - ~Logging(); - void logError(const char* file, int line, const char* fmt, ...); - void logMessage(const char* fmt, ...); - char* getLastError() {return mErrBuf;} - char* getLastMessage() {return mLogBuf;} - -private: - char mErrBuf[4096]; // Arbitrarily large buffer to hold a string - char mLogBuf[4096]; // Arbitrarily large buffer to hold a string - bool mDebug; -#ifdef WIN32 - HANDLE mLoggingMutex; -#else - pthread_mutex_t mLoggingMutex; -#endif -}; - -extern Logging* logg; - -#endif //__LOGGING_H__ diff --git a/drivers/gator/daemon/Makefile b/drivers/gator/daemon/Makefile deleted file mode 100644 index 4aaf219d784..00000000000 --- a/drivers/gator/daemon/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -# -# Makefile for ARM Streamline - Gator Daemon -# - -# Uncomment and define CROSS_COMPILE if it is not already defined -# CROSS_COMPILE=/path/to/cross-compiler/arm-none-linux-gnueabi- -ARCH=arm - -CPP=$(CROSS_COMPILE)g++ - -# -g produces debugging information -# -O3 maximum optimization -# -O0 no optimization, used for debugging -# -Wall enables most warnings -# -Werror treats warnings as errors -# -std=c++0x is the planned new c++ standard -# -std=c++98 is the 1998 c++ standard -# -march=armv5t is required to set the minimum architecture -# -mthumb-interwork is required for interworking to ARM or Thumb stdlibc -CFLAGS=-O3 -Wall -Werror -march=armv5t -mthumb-interwork -TARGET=gatord -CPP_SRC = $(wildcard *.cpp) -TGT_OBJS = $(CPP_SRC:%.cpp=%.o) - -all: $(TARGET) - -%.o: %.cpp *.h - $(CPP) -c $(CFLAGS) -o $@ $< - -$(TARGET): convert $(TGT_OBJS) - $(CPP) -s -o $@ $(TGT_OBJS) -lc -lrt -lpthread - rm 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 - -clean: - rm -f *.o $(TARGET) events.xml events_xml.h configuration_xml.h diff --git a/drivers/gator/daemon/OlySocket.cpp b/drivers/gator/daemon/OlySocket.cpp deleted file mode 100644 index 8a9ca970b94..00000000000 --- a/drivers/gator/daemon/OlySocket.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/** - * 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 -#ifdef WIN32 -#include -#else -#include -#include -#include -#include -#endif -#include "OlySocket.h" -#include "Logging.h" - -#ifdef WIN32 -#define CLOSE_SOCKET(x) closesocket(x) -#define SHUTDOWN_RX_TX SD_BOTH -#define snprintf _snprintf -#else -#define CLOSE_SOCKET(x) close(x) -#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(); - } -#endif - - if (multiple) { - createServerSocket(port); - } else { - createSingleServerConnection(port); - } -} - -OlySocket::OlySocket(int port, char* host) { - fdServer = 0; - createClientSocket(host, port); -} - -OlySocket::~OlySocket() { - 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); -} - -void OlySocket::closeSocket() { - // 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(fdServer) != 0) { - logg->logError(__FILE__, __LINE__, "Failed to close server socket."); - handleException(); - } - fdServer = 0; -} - -void OlySocket::createClientSocket(char* hostname, int portno) { -#ifdef WIN32 - // 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(); - } -#endif -} - -void OlySocket::createSingleServerConnection(int port) { - createServerSocket(port); - - mSocketID = acceptConnection(); - closeServerSocket(); -} - -void OlySocket::createServerSocket(int port) { - // Create socket - fdServer = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (fdServer < 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(fdServer, 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(fdServer, (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(fdServer, 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 (fdServer <= 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(fdServer, 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; - } -} - -// 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; -} - -// 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; -} - -// 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; -} diff --git a/drivers/gator/daemon/OlySocket.h b/drivers/gator/daemon/OlySocket.h deleted file mode 100644 index 2fe6e59516f..00000000000 --- a/drivers/gator/daemon/OlySocket.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * 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. - */ - -#ifndef __OLY_SOCKET_H__ -#define __OLY_SOCKET_H__ - -#include - -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); - char* getLastError() {return strError;} - int getSocketID() {return mSocketID;} -private: - char* strError; - int mSocketID, fdServer; - void createClientSocket(char* hostname, int port); - void createSingleServerConnection(int port); - void createServerSocket(int port); -}; - -#endif //__OLY_SOCKET_H__ diff --git a/drivers/gator/daemon/OlyUtility.cpp b/drivers/gator/daemon/OlyUtility.cpp deleted file mode 100644 index 1b15d33d0e5..00000000000 --- a/drivers/gator/daemon/OlyUtility.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/** - * 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 -#include -#include -#include - -#ifndef WIN32 -#include -#else -#include -#endif - -#include "OlyUtility.h" - -OlyUtility* util = NULL; - -void OlyUtility::stringToLower(char* 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); -#endif - - if (length == sizeOfPath) - return -1; - - fullpath[length] = 0; - fullpath = getPathPart(fullpath); - - 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) return NULL; - - // Copy the file into the buffer - if (fread(buffer, 1, lSize, pFile) != lSize) 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)) 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)) return -1; - - // Terminate - fclose(pFile); - return 0; -} - -/** - * Copies the srcFile into dstFile in 1kB chunks. - * The dstFile will be overwritten if it exists. - * 0 is returned on an error; otherwise 1. - */ -#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; -} - -const char* OlyUtility::getFilePart(const char* path) { - const char* last_sep = strrchr(path, PATH_SEPARATOR); - - // in case path is not a full path - if (last_sep == NULL) { - return path; - } - - return (const char*)((int)last_sep + 1); -} - -// 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); - - // in case path is not a full path - if (last_sep == NULL) { - return 0; - } - *(char*)((int)last_sep + 1) = 0; - - return (path); -} diff --git a/drivers/gator/daemon/OlyUtility.h b/drivers/gator/daemon/OlyUtility.h deleted file mode 100644 index 0fa021dc364..00000000000 --- a/drivers/gator/daemon/OlyUtility.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * 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. - */ - -#ifndef OLY_UTILITY_H -#define OLY_UTILITY_H - -#ifdef WIN32 -#define PATH_SEPARATOR '\\' -#else -#define PATH_SEPARATOR '/' -#endif - -class OlyUtility { -public: - OlyUtility() {}; - ~OlyUtility() {}; - 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: -}; - -extern OlyUtility* util; - -#endif // OLY_UTILITY_H diff --git a/drivers/gator/daemon/RequestXML.cpp b/drivers/gator/daemon/RequestXML.cpp deleted file mode 100644 index e8f24d2d25d..00000000000 --- a/drivers/gator/daemon/RequestXML.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Copyright (C) ARM Limited 2011-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 -#include -#include -#include "RequestXML.h" -#include "Logging.h" - -extern void handleException(); - -static const char* TAG_REQUEST = "request"; - -static const char* ATTR_PROTOCOL = "protocol"; -static const char* ATTR_EVENTS = "events"; -static const char* ATTR_CONFIGURATION = "configuration"; -static const char* ATTR_COUNTERS = "counters"; -static const char* ATTR_SESSION = "session"; -static const char* ATTR_CAPTURED = "captured"; -static const char* ATTR_DEFAULTS = "defaults"; - -RequestXML::RequestXML(const char * str) { - parameters.protocol = false; - parameters.events = false; - parameters.configuration = false; - parameters.counters = false; - parameters.session = false; - parameters.captured = false; - parameters.defaults = false; - - XMLReader reader(str); - char * tag = reader.nextTag(); - while(tag != 0) { - if (strcmp(tag, TAG_REQUEST) == 0) { - requestTag(&reader); - return; - } - tag = reader.nextTag(); - } - - logg->logError(__FILE__, __LINE__, "No request tag found in the request.xml file"); - handleException(); -} - -RequestXML::~RequestXML() { -} - -void RequestXML::requestTag(XMLReader* in) { - parameters.protocol = in->getAttributeAsBoolean(ATTR_PROTOCOL, false); - parameters.events = in->getAttributeAsBoolean(ATTR_EVENTS, false); - parameters.configuration = in->getAttributeAsBoolean(ATTR_CONFIGURATION, false); - parameters.counters = in->getAttributeAsBoolean(ATTR_COUNTERS, false); - parameters.session = in->getAttributeAsBoolean(ATTR_SESSION, false); - parameters.captured = in->getAttributeAsBoolean(ATTR_CAPTURED, false); - parameters.defaults = in->getAttributeAsBoolean(ATTR_DEFAULTS, false); -} diff --git a/drivers/gator/daemon/RequestXML.h b/drivers/gator/daemon/RequestXML.h deleted file mode 100644 index bebd04809ae..00000000000 --- a/drivers/gator/daemon/RequestXML.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * 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. - */ - -#ifndef REQUEST_XML_H -#define REQUEST_XML_H - -#include "XMLReader.h" - -struct ConfigParameters { - bool protocol; - bool events; - bool configuration; - bool counters; - bool session; - bool captured; - bool defaults; -}; - -class RequestXML { -public: - RequestXML(const char * str); - ~RequestXML(); - ConfigParameters parameters; -private: - void requestTag(XMLReader* in); -}; - -#endif // REQUEST_XML_H diff --git a/drivers/gator/daemon/Sender.cpp b/drivers/gator/daemon/Sender.cpp deleted file mode 100644 index 9792c3677a3..00000000000 --- a/drivers/gator/daemon/Sender.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/** - * 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 -#include -#include -#include -#include -#include -#include -#include "Sender.h" -#include "Logging.h" -#include "SessionData.h" - -extern void handleException(); - -Sender::Sender(OlySocket* socket) { - dataFile = NULL; - dataSocket = NULL; - - // Set up the socket connection - if (socket) { - char streamline[64] = {0}; - dataSocket = socket; - - // Receive magic sequence - can wait forever - // Streamline will send data prior to the magic sequence for legacy support, which should be ignored for v4+ - while (strcmp("STREAMLINE", streamline) != 0) { - if (dataSocket->receiveString(streamline, sizeof(streamline)) == -1) { - logg->logError(__FILE__, __LINE__, "Socket disconnected"); - handleException(); - } - } - - // Send magic sequence - must be done first, afterwhich error messages can be sent - char magic[] = {'G', 'A', 'T', 'O', 'R', '\n'}; - dataSocket->send(magic, sizeof(magic)); - - gSessionData->mWaitingOnCommand = true; - logg->logMessage("Completed magic sequence"); - } - - pthread_mutex_init(&sendMutex, NULL); -} - -Sender::~Sender() { - delete dataSocket; - dataSocket = NULL; - if (dataFile) { - fclose(dataFile); - } -} - -void Sender::createDataFile(char* apcDir) { - if (apcDir == NULL) - return; - - dataFileName = (char*)malloc(strlen(apcDir) + 12); - sprintf(dataFileName, "%s/0000000000", apcDir); - dataFile = fopen(dataFileName, "wb"); - if (!dataFile) { - logg->logError(__FILE__, __LINE__, "Failed to open binary file: %s", dataFileName); - handleException(); - } -} - -void Sender::writeData(const char* data, int length, int type) { - if (length < 0 || (data == NULL && length > 0)) { - return; - } - - // Multiple threads call writeData() - pthread_mutex_lock(&sendMutex); - - // Send data over the socket connection - if (dataSocket) { - // Start alarm - alarm(8); - - // Send data over the socket, sending the type and size first - logg->logMessage("Sending data with length %d", length); - dataSocket->send((char*)&type, 1); - dataSocket->send((char*)&length, sizeof(length)); - dataSocket->send((char*)data, length); - - // Stop alarm - alarm(0); - } - - // Write data to disk as long as it is not meta data - if (dataFile && type == RESPONSE_APC_DATA) { - logg->logMessage("Writing data with length %d", length); - // Send data to the data file, storing the size first - if ((fwrite((char*)&length, 1, sizeof(length), dataFile) != sizeof(length)) || (fwrite(data, 1, length, dataFile) != (unsigned int)length)) { - logg->logError(__FILE__, __LINE__, "Failed writing binary file %s", dataFileName); - handleException(); - } - } - - pthread_mutex_unlock(&sendMutex); -} diff --git a/drivers/gator/daemon/Sender.h b/drivers/gator/daemon/Sender.h deleted file mode 100644 index 3444b852b01..00000000000 --- a/drivers/gator/daemon/Sender.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * 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. - */ - -#ifndef __SENDER_H__ -#define __SENDER_H__ - -#include -#include -#include "OlySocket.h" - -enum { - RESPONSE_END = 0, // unused - RESPONSE_XML = 1, - RESPONSE_APC_DATA = 3, - RESPONSE_ACK = 4, - RESPONSE_NAK = 5, - RESPONSE_ERROR = 0xFF -}; - -class Sender { -public: - Sender(OlySocket* socket); - ~Sender(); - void writeData(const char* data, int length, int type); - void createDataFile(char* apcDir); -private: - OlySocket* dataSocket; - FILE* dataFile; - char* dataFileName; - pthread_mutex_t sendMutex; -}; - -#endif //__SENDER_H__ diff --git a/drivers/gator/daemon/SessionData.cpp b/drivers/gator/daemon/SessionData.cpp deleted file mode 100644 index 4adcfcd6c20..00000000000 --- a/drivers/gator/daemon/SessionData.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/** - * 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 -#include "SessionData.h" -#include "SessionXML.h" -#include "Logging.h" -extern void handleException(); - -SessionData* gSessionData = NULL; - -SessionData::SessionData() { - initialize(); -} - -SessionData::~SessionData() { -} - -void SessionData::initialize() { - mWaitingOnCommand = false; - mSessionIsActive = false; - mLocalCapture = false; - mOneShot = false; - strcpy(mCoreName, "unknown"); - configurationXMLPath = NULL; - apcDir = NULL; - mSampleRate = 0; - mDuration = 0; - mBytes = 0; - mBacktraceDepth = 0; - mTotalBufferSize = 0; - mCores = 1; - - initializeCounters(); -} - -void SessionData::initializeCounters() { - // PMU Counters - for (int i = 0; i < MAX_PERFORMANCE_COUNTERS; i++) { - mPerfCounterType[i][0] = 0; - mPerfCounterTitle[i][0] = 0; - mPerfCounterName[i][0] = 0; - mPerfCounterDescription[i][0] = 0; - mPerfCounterEnabled[i] = 0; - mPerfCounterEvent[i] = 0; - mPerfCounterColor[i] = 0; - mPerfCounterKey[i] = 0; - mPerfCounterCount[i] = 0; - mPerfCounterOperation[i][0] = 0; - mPerfCounterPerCPU[i] = false; - mPerfCounterEBSCapable[i] = false; - } -} - -void SessionData::parseSessionXML(char* xmlString) { - SessionXML session(xmlString); - session.parse(); - - // Parameter error checking - if (session.parameters.output_path == 0 && session.parameters.target_path == 0) { - logg->logError(__FILE__, __LINE__, "No capture path (target or host) was provided."); - handleException(); - } else if (gSessionData->mLocalCapture && session.parameters.target_path == 0) { - logg->logError(__FILE__, __LINE__, "Missing target_path tag in session xml required for a local capture."); - handleException(); - } - - // Set session data values - if (strcmp(session.parameters.sample_rate, "high") == 0) { - gSessionData->mSampleRate = 10000; - } else if (strcmp(session.parameters.sample_rate, "normal") == 0) { - gSessionData->mSampleRate = 1000; - } else { // "low" - gSessionData->mSampleRate = 100; - } - gSessionData->mBacktraceDepth = session.parameters.call_stack_unwinding == true ? 128 : 0; - gSessionData->mDuration = session.parameters.duration; - - // Determine buffer size (in MB) based on buffer mode - gSessionData->mOneShot = true; - if (strcmp(session.parameters.buffer_mode, "streaming") == 0) { - gSessionData->mOneShot = false; - gSessionData->mTotalBufferSize = 1; - } else if (strcmp(session.parameters.buffer_mode, "small") == 0) { - gSessionData->mTotalBufferSize = 1; - } else if (strcmp(session.parameters.buffer_mode, "normal") == 0) { - gSessionData->mTotalBufferSize = 4; - } else if (strcmp(session.parameters.buffer_mode, "large") == 0) { - gSessionData->mTotalBufferSize = 16; - } else { - logg->logError(__FILE__, __LINE__, "Invalid value for buffer mode in session xml."); - handleException(); - } - - gSessionData->images = session.parameters.images; - gSessionData->target_path = session.parameters.target_path; - gSessionData->title = session.parameters.title; -} diff --git a/drivers/gator/daemon/SessionData.h b/drivers/gator/daemon/SessionData.h deleted file mode 100644 index cc188f8e694..00000000000 --- a/drivers/gator/daemon/SessionData.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * 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. - */ - -#ifndef SESSION_DATA_H -#define SESSION_DATA_H - -#define MAX_PERFORMANCE_COUNTERS 50 -#define MAX_STRING_LEN 80 -#define MAX_DESCRIPTION_LEN 400 - -#define PROTOCOL_VERSION 8 -#define PROTOCOL_DEV 1000 // Differentiates development versions (timestamp) from release versions - -struct ImageLinkList { - char *path; - struct ImageLinkList *next; -}; - -class SessionData { -public: - SessionData(); - ~SessionData(); - void initialize(); - void initializeCounters(); - void parseSessionXML(char* xmlString); - - char mCoreName[MAX_STRING_LEN]; - struct ImageLinkList *images; - char* configurationXMLPath; - char* target_path; - char* apcDir; - char* title; - - bool mWaitingOnCommand; - bool mSessionIsActive; - bool mLocalCapture; - bool mOneShot; // halt processing of the driver data until profiling is complete or the buffer is filled - - int mBacktraceDepth; - int mTotalBufferSize; // approximate number of MB to use for the entire collection buffer, the actual amount is a multiple based on a buffer size retrieved from the driver - int mSampleRate; - int mDuration; - int mCores; - int mBytes; - - // PMU Counters - char mPerfCounterType[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; - char mPerfCounterTitle[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; - char mPerfCounterName[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; - char mPerfCounterDescription[MAX_PERFORMANCE_COUNTERS][MAX_DESCRIPTION_LEN]; - int mPerfCounterEnabled[MAX_PERFORMANCE_COUNTERS]; - int mPerfCounterEvent[MAX_PERFORMANCE_COUNTERS]; - int mPerfCounterColor[MAX_PERFORMANCE_COUNTERS]; - int mPerfCounterCount[MAX_PERFORMANCE_COUNTERS]; - int mPerfCounterKey[MAX_PERFORMANCE_COUNTERS]; - bool mPerfCounterPerCPU[MAX_PERFORMANCE_COUNTERS]; - bool mPerfCounterEBSCapable[MAX_PERFORMANCE_COUNTERS]; - char mPerfCounterOperation[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; -}; - -extern SessionData* gSessionData; - -#endif // SESSION_DATA_H diff --git a/drivers/gator/daemon/SessionXML.cpp b/drivers/gator/daemon/SessionXML.cpp deleted file mode 100644 index 4604d7cf193..00000000000 --- a/drivers/gator/daemon/SessionXML.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/** - * 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 -#include -#include -#include "SessionXML.h" -#include "Logging.h" - -extern void handleException(); - -static const char* TAG_SESSION = "session"; -static const char* TAG_IMAGE = "image"; - -static const char* ATTR_VERSION = "version"; -static const char* ATTR_TITLE = "title"; -static const char* ATTR_UUID = "uuid"; -static const char* ATTR_CALL_STACK_UNWINDING = "call_stack_unwinding"; -static const char* ATTR_BUFFER_MODE = "buffer_mode"; -static const char* ATTR_SAMPLE_RATE = "sample_rate"; -static const char* ATTR_TARGET_PATH = "target_path"; -static const char* ATTR_OUTPUT_PATH = "output_path"; -static const char* ATTR_DURATION = "duration"; -static const char* ATTR_PATH = "path"; - -SessionXML::SessionXML(const char * str) { - parameters.title = 0; - parameters.uuid[0] = 0; - parameters.target_path = 0; - parameters.output_path = 0; - parameters.buffer_mode[0] = 0; - parameters.sample_rate[0] = 0; - parameters.duration = 0; - parameters.call_stack_unwinding = false; - parameters.images = NULL; - mPath = 0; - mSessionXML = (char*)str; - logg->logMessage(mSessionXML); -} - -SessionXML::~SessionXML() { - if (mPath != 0) { - free(mSessionXML); - } -} - -void SessionXML::parse() { - XMLReader reader(mSessionXML); - char * tag = reader.nextTag(); - while(tag != 0) { - if (strcmp(tag, TAG_SESSION) == 0) { - sessionTag(&reader); - return; - } - tag = reader.nextTag(); - } - - logg->logError(__FILE__, __LINE__, "No session tag found in the session.xml file"); - handleException(); -} - -void SessionXML::sessionTag(XMLReader* in) { - char* tempBuffer = (char*)malloc(PATH_MAX); - int version = in->getAttributeAsInteger(ATTR_VERSION, 0); - if (version != 1) { - logg->logError(__FILE__, __LINE__, "Invalid session.xml version: %d", version); - handleException(); - } - - in->getAttribute(ATTR_TITLE, tempBuffer, PATH_MAX, "unnamed"); - parameters.title = strdup(tempBuffer); // freed when the child process exits - if (parameters.title == NULL) { - logg->logError(__FILE__, __LINE__, "failed to allocate parameters.title (%d bytes)", strlen(tempBuffer)); - handleException(); - } - in->getAttribute(ATTR_UUID, parameters.uuid, sizeof(parameters.uuid), ""); - parameters.duration = in->getAttributeAsInteger(ATTR_DURATION, 0); - parameters.call_stack_unwinding = in->getAttributeAsBoolean(ATTR_CALL_STACK_UNWINDING, true); - in->getAttribute(ATTR_BUFFER_MODE, parameters.buffer_mode, sizeof(parameters.buffer_mode), "normal"); - in->getAttribute(ATTR_SAMPLE_RATE, parameters.sample_rate, sizeof(parameters.sample_rate), ""); - in->getAttribute(ATTR_TARGET_PATH, tempBuffer, PATH_MAX, ""); - parameters.target_path = strdup(tempBuffer); // freed when the child process exits - if (parameters.target_path == NULL) { - logg->logError(__FILE__, __LINE__, "failed to allocate parameters.target_path (%d bytes)", strlen(tempBuffer)); - handleException(); - } - in->getAttribute(ATTR_OUTPUT_PATH, tempBuffer, PATH_MAX, ""); - parameters.output_path = strdup(tempBuffer); // freed when the child process exits - if (parameters.output_path == NULL) { - logg->logError(__FILE__, __LINE__, "failed to allocate parameters.output_path (%d bytes)", strlen(tempBuffer)); - handleException(); - } - - free(tempBuffer); - - char * tag = in->nextTag(); - while(tag != 0) { - if (strcmp(tag, TAG_IMAGE) == 0) { - sessionImage(in); - } - tag = in->nextTag(); - } -} - -void SessionXML::sessionImage(XMLReader* in) { - int length = in->getAttributeLength(ATTR_PATH); - struct ImageLinkList *image; - - image = (struct ImageLinkList *)malloc(sizeof(struct ImageLinkList)); - image->path = (char *)malloc(length + 1); - in->getAttribute(ATTR_PATH, image->path, length + 1, ""); - image->next = parameters.images; - parameters.images = image; -} diff --git a/drivers/gator/daemon/SessionXML.h b/drivers/gator/daemon/SessionXML.h deleted file mode 100644 index 4649685bc9e..00000000000 --- a/drivers/gator/daemon/SessionXML.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * 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. - */ - -#ifndef SESSION_XML_H -#define SESSION_XML_H - -#include "XMLReader.h" -#include "SessionData.h" - -struct ConfigParameters { - char* title; // status title - char uuid[64]; // universal unique identifier - char* target_path; // target path of where to write to disk - char* output_path; // host path of where to write to disk - char buffer_mode[64]; // buffer mode, "streaming", "low", "normal", "high" defines oneshot and buffer size - char sample_rate[64]; // capture mode, "high", "normal", or "low" - int duration; // length of profile in seconds - bool call_stack_unwinding; // whether stack unwinding is performed - struct ImageLinkList *images; // linked list of image strings -}; - -class SessionXML { -public: - SessionXML(const char * str); - ~SessionXML(); - void parse(); - ConfigParameters parameters; -private: - char* mSessionXML; - char* mPath; - void sessionTag(XMLReader* in); - void sessionImage(XMLReader* in); -}; - -#endif // SESSION_XML_H diff --git a/drivers/gator/daemon/StreamlineSetup.cpp b/drivers/gator/daemon/StreamlineSetup.cpp deleted file mode 100644 index 5662ee8c76f..00000000000 --- a/drivers/gator/daemon/StreamlineSetup.cpp +++ /dev/null @@ -1,321 +0,0 @@ -/** - * Copyright (C) ARM Limited 2011-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 -#include -#include -#include -#include -#include -#include -#include -#include "XMLOut.h" -#include "Sender.h" -#include "Logging.h" -#include "XMLReader.h" -#include "RequestXML.h" -#include "OlyUtility.h" -#include "SessionData.h" -#include "CapturedXML.h" -#include "StreamlineSetup.h" -#include "ConfigurationXML.h" - -extern void handleException(); - -static const char* TAG_SESSION = "session"; -static const char* TAG_CONFIGURATIONS = "configurations"; - -StreamlineSetup::StreamlineSetup(OlySocket* s) { - bool ready = false; - char *data = NULL; - int type; - - socket = s; - mSessionXML = NULL; - - // Receive commands from Streamline (master) - while (!ready) { - // receive command over socket - gSessionData->mWaitingOnCommand = true; - data = readCommand(&type); - - // parse and handle data - switch (type) { - case COMMAND_REQUEST_XML: - handleRequest(data); - break; - case COMMAND_DELIVER_XML: - handleDeliver(data); - break; - case COMMAND_APC_START: - logg->logMessage("Received apc start request"); - ready = true; - break; - case COMMAND_APC_STOP: - logg->logMessage("Received apc stop request before apc start request"); - exit(0); - break; - case COMMAND_DISCONNECT: - logg->logMessage("Received disconnect command"); - exit(0); - break; - case COMMAND_PING: - logg->logMessage("Received ping command"); - sendData(NULL, 0, RESPONSE_ACK); - break; - default: - logg->logError(__FILE__, __LINE__, "Target error: Unknown command type, %d", type); - handleException(); - } - - delete(data); - } -} - -StreamlineSetup::~StreamlineSetup() { - if (mSessionXML) - free(mSessionXML); -} - -char* StreamlineSetup::readCommand(int* command) { - char type; - char* data; - int response, length; - - // receive type - response = socket->receiveNBytes(&type, sizeof(type)); - - // After receiving a single byte, we are no longer waiting on a command - gSessionData->mWaitingOnCommand = false; - - if (response < 0) { - logg->logError(__FILE__, __LINE__, "Target error: Unexpected socket disconnect"); - handleException(); - } - - // receive length - response = socket->receiveNBytes((char*)&length, sizeof(length)); - if (response < 0) { - logg->logError(__FILE__, __LINE__, "Target error: Unexpected socket disconnect"); - handleException(); - } - - // add artificial limit - if ((length < 0) || length > 1024 * 1024) { - logg->logError(__FILE__, __LINE__, "Target error: Invalid length received, %d", length); - handleException(); - } - - // allocate memory to contain the xml file, size of zero returns a zero size object - data = (char*)calloc(length + 1, 1); - if (data == NULL) { - logg->logError(__FILE__, __LINE__, "Unable to allocate memory for xml"); - handleException(); - } - - // receive data - response = socket->receiveNBytes(data, length); - if (response < 0) { - logg->logError(__FILE__, __LINE__, "Target error: Unexpected socket disconnect"); - handleException(); - } - - // null terminate the data for string parsing - if (length > 0) { - data[length] = 0; - } - - *command = type; - return data; -} - -void StreamlineSetup::handleRequest(char* xml) { - RequestXML request(xml); - - if (request.parameters.protocol) { - sendProtocol(); - logg->logMessage("Sent protocol xml response"); - } else if (request.parameters.events) { - sendEvents(); - logg->logMessage("Sent events xml response"); - } else if (request.parameters.configuration) { - sendConfiguration(); - logg->logMessage("Sent configuration xml response"); - } else if (request.parameters.counters) { - sendCounters(); - logg->logMessage("Sent counters xml response"); - } else if (request.parameters.session) { - sendData(mSessionXML, strlen(mSessionXML), RESPONSE_XML); - logg->logMessage("Sent session xml response"); - } else if (request.parameters.captured) { - CapturedXML capturedXML; - const char* capturedText = capturedXML.getXML(); - sendData(capturedText, strlen(capturedText), RESPONSE_XML); - logg->logMessage("Sent captured xml response"); - } else if (request.parameters.defaults) { - sendDefaults(); - logg->logMessage("Sent default configuration xml response"); - } else { - char error[] = "Unknown request"; - sendData(error, strlen(error), RESPONSE_NAK); - logg->logMessage("Received unknown request:\n%s", xml); - } -} - -typedef enum {UNKNOWN, SESSION_XML, CONFIGURATION_XML} delivery_type_t; -void StreamlineSetup::handleDeliver(char* xml) { - delivery_type_t type = UNKNOWN; - - // Determine xml type - XMLReader reader(xml); - char * tag = reader.nextTag(); - while(tag != 0) { - if (strcmp(tag, TAG_SESSION) == 0) { - type = SESSION_XML; - break; - } else if (strcmp(tag, TAG_CONFIGURATIONS) == 0) { - type = CONFIGURATION_XML; - break; - } - tag = reader.nextTag(); - } - - switch (type) { - case UNKNOWN: - logg->logMessage("Received unknown delivery type: %d", type); - sendData(NULL, 0, RESPONSE_NAK); - break; - case SESSION_XML: - // Parse the session xml - gSessionData->parseSessionXML(xml); - - // Save xml - mSessionXML = strdup(xml); - if (mSessionXML == NULL) { - logg->logError(__FILE__, __LINE__, "malloc failed for size %d", strlen(xml) + 1); - handleException(); - } - sendData(NULL, 0, RESPONSE_ACK); - logg->logMessage("Received session xml"); - break; - case CONFIGURATION_XML: - writeConfiguration(xml); - sendData(NULL, 0, RESPONSE_ACK); - logg->logMessage("Received configuration xml"); - break; - } -} - -void StreamlineSetup::sendData(const char* data, int length, int type) { - socket->send((char*)&type, 1); - socket->send((char*)&length, sizeof(length)); - socket->send((char*)data, length); -} - -void StreamlineSetup::sendProtocol() { - XMLOut out; - out.xmlHeader(); - - out.startElement("protocol"); - out.attributeInt("version", PROTOCOL_VERSION); - out.endElement("protocol"); - - sendString(out.getXmlString(), RESPONSE_XML); -} - -void StreamlineSetup::sendEvents() { -#include "events_xml.h" // defines and initializes char events_xml[] and int events_xml_len - char* path = (char*)malloc(PATH_MAX);; - char* buffer; - unsigned int size = 0; - - util->getApplicationFullPath(path, PATH_MAX); - strncat(path, "events.xml", PATH_MAX - strlen(path) - 1); - buffer = util->readFromDisk(path, &size); - if (buffer == NULL) { - logg->logMessage("Unable to locate events.xml, using default"); - buffer = (char*)events_xml; - size = events_xml_len; - } - - sendData(buffer, size, RESPONSE_XML); - if (buffer != (char*)events_xml) { - free(buffer); - } - free(path); -} - -void StreamlineSetup::sendConfiguration() { - ConfigurationXML xml; - - const char* string = xml.getConfigurationXML(); - sendData(string, strlen(string), RESPONSE_XML); -} - -void StreamlineSetup::sendDefaults() { -#include "configuration_xml.h" // defines and initializes char configuration_xml[] and int configuration_xml_len - // Send the config built into the binary - char* xml = (char*)configuration_xml; - unsigned int size = configuration_xml_len; - - // Artificial size restriction - if (size > 1024*1024) { - logg->logError(__FILE__, __LINE__, "Corrupt default configuration file"); - handleException(); - } - - sendData(xml, size, RESPONSE_XML); -} - -#include -void StreamlineSetup::sendCounters() { - XMLOut out; - struct dirent *ent; - - // counters.xml is simply a file listing of /dev/gator/events - DIR* dir = opendir("/dev/gator/events"); - if (dir == NULL) { - logg->logError(__FILE__, __LINE__, "Cannot create counters.xml since unable to read /dev/gator/events"); - handleException(); - } - - out.xmlHeader(); - out.startElement("counters"); - while ((ent = readdir(dir)) != NULL) { - // skip hidden files, current dir, and parent dir - if (ent->d_name[0] == '.') - continue; - out.startElement("counter"); - out.attributeString("name", ent->d_name); - out.endElement("counter"); - } - out.endElement("counters"); - closedir (dir); - - sendString(out.getXmlString(), RESPONSE_XML); -} - -void StreamlineSetup::writeConfiguration(char* xml) { - char* path = (char*)malloc(PATH_MAX); - - if (gSessionData->configurationXMLPath) { - strncpy(path, gSessionData->configurationXMLPath, PATH_MAX); - } else { - util->getApplicationFullPath(path, PATH_MAX); - strncat(path, "configuration.xml", PATH_MAX - strlen(path) - 1); - } - - if (util->writeToDisk(path, xml) < 0) { - logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify write permissions to this path.", path); - handleException(); - } - - // Re-populate gSessionData with the configuration, as it has now changed - new ConfigurationXML(); - free(path); -} diff --git a/drivers/gator/daemon/StreamlineSetup.h b/drivers/gator/daemon/StreamlineSetup.h deleted file mode 100644 index 10327e00bc7..00000000000 --- a/drivers/gator/daemon/StreamlineSetup.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * 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. - */ - -#ifndef __STREAMLINE_SETUP_H__ -#define __STREAMLINE_SETUP_H__ - -#include "OlySocket.h" - -// Commands from Streamline -enum { - COMMAND_REQUEST_XML = 0, - COMMAND_DELIVER_XML = 1, - COMMAND_APC_START = 2, - COMMAND_APC_STOP = 3, - COMMAND_DISCONNECT = 4, - COMMAND_PING = 5 -}; - -class StreamlineSetup { -public: - StreamlineSetup(OlySocket *socket); - ~StreamlineSetup(); -private: - int numConnections; - OlySocket* socket; - char* mSessionXML; - - char* readCommand(int*); - void handleRequest(char* xml); - void handleDeliver(char* xml); - void sendData(const char* data, int length, int type); - void sendString(const char* string, int type) {sendData(string, strlen(string), type);} - void sendProtocol(); - void sendEvents(); - void sendConfiguration(); - void sendDefaults(); - void sendCounters(); - void writeConfiguration(char* xml); -}; - -#endif //__STREAMLINE_SETUP_H__ diff --git a/drivers/gator/daemon/XMLOut.cpp b/drivers/gator/daemon/XMLOut.cpp deleted file mode 100644 index c194fc0042d..00000000000 --- a/drivers/gator/daemon/XMLOut.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/** - * 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 -#include -#include -#include "XMLOut.h" - -XMLOut::XMLOut() { - indent = 0; - incomplete = false; - xml_string[0] = 0; -} - -XMLOut::~XMLOut() { -} - -void XMLOut::writeTabs() { - for (int i = 0; i < indent; i++) { - writeData(" "); - } -} - -void XMLOut::encodeAttributeData(const char* data) { - if (data) { - while (*data) { - char ch = *data++; - - if (ch == '<') { - writeData("<"); - } else if (ch == '>') { - writeData(">"); - } else if (ch == '&') { - writeData("&"); - } else if (ch == '"') { - writeData("""); - } else if (ch == '\'') { - writeData("'"); - } else if (ch >= ' ' && ch <= '~') { - writeData("%c",ch); - } else { - writeData("&#%u;",(unsigned int)ch); - } - } - } -} - -void XMLOut::writeData(const char *format, ...) { - va_list ap; - - va_start(ap, format); - vsnprintf(temp_buffer, sizeof(temp_buffer), format, ap); - va_end(ap); - - strncat(xml_string, temp_buffer, sizeof(xml_string) - strlen(xml_string) - 1); -} - -const XMLOut & XMLOut::xmlHeader(void) { - writeData("\n"); - incomplete = false; - return *this; -} - -const XMLOut & XMLOut::comment(const char* text, const bool newline) { - if (incomplete) { - writeData(">\n"); - } - writeTabs(); - writeData("", text); - if (newline) { - writeData("\n"); - } - incomplete = false; - return *this; -} - -const XMLOut & XMLOut::startElement(const char* tag) { - if (incomplete) { - writeData(">\n"); - } - writeTabs(); - writeData("<%s", tag); - incomplete = true; - indent++; - return *this; -} - -const XMLOut & XMLOut::startElement(const char* tag, int index) { - if (incomplete) { - writeData(">\n"); - } - writeTabs(); - writeData("", index); - writeData("<%s", tag); - incomplete = true; - indent++; - return *this; -} - -const XMLOut & XMLOut::endElement(const char* tag) { - indent--; - if (indent < 0) { - indent = 0; - } - if (incomplete) { - writeData("/>\n"); - incomplete = false; - } else { - writeTabs(); - writeData("\n", tag); - } - return *this; -} - -const XMLOut & XMLOut::attributeString(const char* name, const char* value) { - writeData(" %s=\"", name); - encodeAttributeData(value); - writeData("\""); - return *this; -} - -const XMLOut & XMLOut::attributeInt(const char* name, int value) { - writeData(" %s=\"%d\"", name, value); - return *this; -} - -const XMLOut & XMLOut::attributeUInt(const char* name, unsigned int value) { - writeData(" %s=\"%u\"", name, value); - return *this; -} - -const XMLOut & XMLOut::attributeLong(const char* name, long value) { - writeData(" %s=\"%ld\"", name, value); - return *this; -} - -const XMLOut & XMLOut::attributeULong(const char* name, unsigned long value) { - writeData(" %s=\"%lu\"", name, value); - return *this; -} - -const XMLOut & XMLOut::attributeLongLong(const char* name, long long value) { - writeData(" %s=\"%lld\"", name, value); - return *this; -} - -const XMLOut & XMLOut::attributeULongLong(const char* name, unsigned long long value) { - writeData(" %s=\"%llu\"", name, value); - return *this; -} - -const XMLOut & XMLOut::attributeDouble(const char* name, double value) { - writeData(" %s=\"%f\"", name, value); - return *this; -} - -const XMLOut & XMLOut::attributeBool(const char* name, bool value) { - writeData(" %s=\"%s\"", name, value ? "yes" : "no"); - return *this; -} - -const XMLOut & XMLOut::attributeHex4(const char* name, int value) { - writeData(" %s=\"0x%04x\"", name, value); - return *this; -} - -const XMLOut & XMLOut::attributeHex8(const char* name, int value) { - writeData(" %s=\"0x%08x\"", name, value); - return *this; -} diff --git a/drivers/gator/daemon/XMLOut.h b/drivers/gator/daemon/XMLOut.h deleted file mode 100644 index 3af253dbe83..00000000000 --- a/drivers/gator/daemon/XMLOut.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * 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. - */ - -#ifndef __XMLOUT_H -#define __XMLOUT_H - -class XMLOut { - int indent; - bool incomplete; - char temp_buffer[4096]; // arbitrarilly large buffer to hold variable arguments - char xml_string[64*1024]; // arbitrarilly large buffer to hold an xml file output by the daemon - - void writeTabs(); - void encodeAttributeData(const char* data); - void writeData(const char *format, ...); - -public: - XMLOut(); - ~XMLOut(); - char* getXmlString() {return xml_string;} - void clearXmlString() {xml_string[0]=0;} - const XMLOut & xmlHeader(void); - const XMLOut & comment(const char* text, const bool newline); - const XMLOut & startElement(const char* tag); - const XMLOut & startElement(const char* tag, int index); - const XMLOut & endElement(const char* tag); - const XMLOut & attributeString(const char* name, const char* value); - const XMLOut & attributeInt(const char* name, int value); - const XMLOut & attributeUInt(const char* name, unsigned int value); - const XMLOut & attributeLong(const char* name, long value); - const XMLOut & attributeULong(const char* name, unsigned long value); - const XMLOut & attributeLongLong(const char* name, long long value); - const XMLOut & attributeULongLong(const char* name, unsigned long long value); - const XMLOut & attributeDouble(const char* name, double value); - const XMLOut & attributeBool(const char* name, bool value); - const XMLOut & attributeHex4(const char* name, int value); - const XMLOut & attributeHex8(const char* name, int value); -}; - -#endif // __XMLOUT_H diff --git a/drivers/gator/daemon/XMLReader.cpp b/drivers/gator/daemon/XMLReader.cpp deleted file mode 100644 index 77c76e29d73..00000000000 --- a/drivers/gator/daemon/XMLReader.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/** - * 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 -#include -#include -#include "XMLReader.h" -extern void handleException(); - -XMLReader::XMLReader(const char* xmlstring) { - mPtr = (char*)xmlstring; - mNoMore = false; - mFirstTime = true; -} - -XMLReader::~XMLReader() { -} - -char* XMLReader::nextTag() { - static char tag[128]; // arbitrarily set max tag size to 127 characters + nul - - // Check if past the end of the root tag - if (mNoMore) return NULL; - - // Find start character - mPtr = strchr(mPtr, '<'); - - if (mPtr == NULL) return mPtr; - - // Skip tag if it begins with '); - if (end == NULL) - return 0; - - // Check if tag has no attributes - char* tagend = strchr(mPtr, '>'); - if (tagend < end) end = tagend; - - // Check the tag name length - unsigned int length = (int)end - (int)mPtr; - if (length > sizeof(tag) - 1) { - // tag name too long, skip it - return nextTag(); - } - - // Return the tag name - strncpy(tag, mPtr, length); - tag[length] = 0; - - // Mark the root tag - if (mFirstTime) { - mEndXML[0] = '/'; - strcpy(&mEndXML[1], tag); - mFirstTime = false; - } else if (strcmp(tag, mEndXML) == 0) { - // End of root tag found - mNoMore = true; - } - - return tag; -} - -void XMLReader::getAttribute(const char* name, char* value, int maxSize, const char* defValue) { - char searchString[128]; - - // Set up default - strncpy(value, defValue, maxSize - 1); - value[maxSize - 1] = 0; - - // Determine search string by ending the name with =" - if (strlen(name) > sizeof(searchString) - 3) return; - strcpy(searchString, name); - strcat(searchString, "=\""); - - // Find the beginning of the attribute's search string - char* begin = strstr(mPtr, searchString); - if (begin == NULL) return; - - // Find the beginning of the attribute's value - begin += strlen(searchString); - - // Find the end of the current tag to make sure the attribute exists within the tag - char* endtag = strchr(mPtr, '>'); - if (endtag < begin) return; - - // Find the end of the attribute's value - char* end = strchr(begin, '"'); - if (end == NULL) return; - - // Determine length - int length = (int)end - (int)begin; - if (length > maxSize - 1) return; - - strncpy(value, begin, length); - value[length] = 0; -} - -int XMLReader::getAttributeAsInteger(const char* name, int defValue) { - char value[32]; - getAttribute(name, value, sizeof(value), ""); - if (value[0] == 0) return defValue; - if (value[0] == '0' && value[1] == 'x') { - return (int) strtoul(&value[2], (char**)NULL, 16); - } - return strtol(value, NULL, 10); -} - -bool XMLReader::getAttributeAsBoolean(const char* name, bool defValue) { - char value[32]; - getAttribute(name, value, sizeof(value), ""); - if (value[0] == 0) return defValue; - - // 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; -} - -int XMLReader::getAttributeLength(const char* name) { - char searchString[128]; // arbitrarily large amount - - // Determine search string by ending the name with =" - if (strlen(name) > sizeof(searchString) - 3) return 0; - strcpy(searchString, name); - strcat(searchString, "=\""); - - // Find the beginning of the attribute's search string - char* begin = strstr(mPtr, searchString); - if (begin == NULL) return 0; - - // Find the beginning of the attribute's value - begin += strlen(searchString); - - // Find the end of the current tag to make sure the attribute exists within the tag - char* endtag = strchr(mPtr, '>'); - if (endtag < begin) return 0; - - // Find the end of the attribute's value - char* end = strchr(begin, '"'); - if (end == NULL) return 0; - - // Determine length - return (int)end - (int)begin; -} diff --git a/drivers/gator/daemon/XMLReader.h b/drivers/gator/daemon/XMLReader.h deleted file mode 100644 index ac0098add0a..00000000000 --- a/drivers/gator/daemon/XMLReader.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - * 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. - */ - -#ifndef _XMLREADER_H -#define _XMLREADER_H - -class XMLReader { -public: - XMLReader(const char* xmlstring); - ~XMLReader(); - char* nextTag(); - void getAttribute(const char* name, char* value, int maxSize, const char* defValue); - int getAttributeAsInteger(const char* name, int defValue); - bool getAttributeAsBoolean(const char* name, bool defValue); - int getAttributeLength(const char* name); -private: - char* mPtr; - bool mFirstTime, mNoMore; - char mEndXML[128]; -}; - -#endif // _XMLREADER_H diff --git a/drivers/gator/daemon/configuration.xml b/drivers/gator/daemon/configuration.xml deleted file mode 100644 index 0f910651950..00000000000 --- a/drivers/gator/daemon/configuration.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/drivers/gator/daemon/events-ARM11.xml b/drivers/gator/daemon/events-ARM11.xml deleted file mode 100644 index 5742271c29b..00000000000 --- a/drivers/gator/daemon/events-ARM11.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/drivers/gator/daemon/events-ARM11MPCore.xml b/drivers/gator/daemon/events-ARM11MPCore.xml deleted file mode 100644 index 6da9ecb49dd..00000000000 --- a/drivers/gator/daemon/events-ARM11MPCore.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/drivers/gator/daemon/events-Cortex-A15.xml b/drivers/gator/daemon/events-Cortex-A15.xml deleted file mode 100644 index 86a3d17e9d8..00000000000 --- a/drivers/gator/daemon/events-Cortex-A15.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/drivers/gator/daemon/events-Cortex-A5.xml b/drivers/gator/daemon/events-Cortex-A5.xml deleted file mode 100644 index 3683947cbe5..00000000000 --- a/drivers/gator/daemon/events-Cortex-A5.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/drivers/gator/daemon/events-Cortex-A7.xml b/drivers/gator/daemon/events-Cortex-A7.xml deleted file mode 100644 index db9f180ca10..00000000000 --- a/drivers/gator/daemon/events-Cortex-A7.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/drivers/gator/daemon/events-Cortex-A8.xml b/drivers/gator/daemon/events-Cortex-A8.xml deleted file mode 100644 index f3396b71144..00000000000 --- a/drivers/gator/daemon/events-Cortex-A8.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/drivers/gator/daemon/events-Cortex-A9.xml b/drivers/gator/daemon/events-Cortex-A9.xml deleted file mode 100644 index 1edb54a9359..00000000000 --- a/drivers/gator/daemon/events-Cortex-A9.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/drivers/gator/daemon/events-Krait-architected.xml b/drivers/gator/daemon/events-Krait-architected.xml deleted file mode 100644 index 46d6a616b05..00000000000 --- a/drivers/gator/daemon/events-Krait-architected.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/drivers/gator/daemon/events-L2C-310.xml b/drivers/gator/daemon/events-L2C-310.xml deleted file mode 100644 index b1cd8dff5b5..00000000000 --- a/drivers/gator/daemon/events-L2C-310.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/drivers/gator/daemon/events-Linux.xml b/drivers/gator/daemon/events-Linux.xml deleted file mode 100644 index 338e1605506..00000000000 --- a/drivers/gator/daemon/events-Linux.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/drivers/gator/daemon/events-Mali-400.xml b/drivers/gator/daemon/events-Mali-400.xml deleted file mode 100644 index f64fec8aaac..00000000000 --- a/drivers/gator/daemon/events-Mali-400.xml +++ /dev/null @@ -1,395 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/drivers/gator/daemon/events-Scorpion.xml b/drivers/gator/daemon/events-Scorpion.xml deleted file mode 100644 index 8ad196a2dbf..00000000000 --- a/drivers/gator/daemon/events-Scorpion.xml +++ /dev/null @@ -1,113 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/drivers/gator/daemon/events-ScorpionMP.xml b/drivers/gator/daemon/events-ScorpionMP.xml deleted file mode 100644 index bd13b8a9b3a..00000000000 --- a/drivers/gator/daemon/events-ScorpionMP.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/drivers/gator/daemon/events_footer.xml b/drivers/gator/daemon/events_footer.xml deleted file mode 100644 index cd2b44665ba..00000000000 --- a/drivers/gator/daemon/events_footer.xml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/drivers/gator/daemon/events_header.xml b/drivers/gator/daemon/events_header.xml deleted file mode 100644 index 38ec4c03246..00000000000 --- a/drivers/gator/daemon/events_header.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/drivers/gator/daemon/main.cpp b/drivers/gator/daemon/main.cpp deleted file mode 100644 index 51237cbcf75..00000000000 --- a/drivers/gator/daemon/main.cpp +++ /dev/null @@ -1,306 +0,0 @@ -/** - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "Child.h" -#include "SessionData.h" -#include "OlySocket.h" -#include "Logging.h" -#include "OlyUtility.h" - -#define DEBUG false - -extern Child* child; -extern void handleException(); -int shutdownFilesystem(); -static pthread_mutex_t numSessions_mutex; -static int numSessions = 0; -static OlySocket* socket = NULL; -static bool driverRunningAtStart = false; -static bool driverMountedAtStart = false; - -struct cmdline_t { - int port; - char* sessionXML; -}; - -void cleanUp() { - if (shutdownFilesystem() == -1) { - logg->logMessage("Error shutting down gator filesystem"); - } - delete socket; - delete util; - delete logg; -} - -// CTRL C Signal Handler -void handler(int signum) { - logg->logMessage("Received signal %d, gator daemon exiting", signum); - - // Case 1: both child and parent receive the signal - if (numSessions > 0) { - // Arbitrary sleep of 1 second to give time for the child to exit; - // if something bad happens, continue the shutdown process regardless - sleep(1); - } - - // Case 2: only the parent received the signal - if (numSessions > 0) { - // Kill child threads - the first signal exits gracefully - logg->logMessage("Killing process group as %d child was running when signal was received", numSessions); - kill(0, SIGINT); - - // Give time for the child to exit - sleep(1); - - if (numSessions > 0) { - // The second signal force kills the child - logg->logMessage("Force kill the child"); - kill(0, SIGINT); - // Again, sleep for 1 second - sleep(1); - - if (numSessions > 0) { - // Something bad has really happened; the child is not exiting and therefore may hold the /dev/gator resource open - printf("Unable to kill the gatord child process, thus gator.ko may still be loaded.\n"); - } - } - } - - cleanUp(); - exit(0); -} - -// Child exit Signal Handler -void child_exit(int signum) { - int status; - int pid = wait(&status); - if (pid != -1) { - pthread_mutex_lock(&numSessions_mutex); - numSessions--; - pthread_mutex_unlock(&numSessions_mutex); - logg->logMessage("Child process %d exited with status %d", pid, status); - } -} - -// retval: -1 = failure; 0 = was already mounted; 1 = successfully mounted -int mountGatorFS() { - // If already mounted, - if (access("/dev/gator/buffer", F_OK) == 0) - return 0; - - // else, mount the filesystem - mkdir("/dev/gator", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - if (mount("nodev", "/dev/gator", "gatorfs", 0, NULL) != 0) - return -1; - else - return 1; -} - -int setupFilesystem() { - int retval; - - // Verify root permissions - uid_t euid = geteuid(); - if (euid) { - logg->logError(__FILE__, __LINE__, "gatord must be launched with root privileges"); - handleException(); - } - - retval = mountGatorFS(); - if (retval == 1) { - logg->logMessage("Driver already running at startup"); - driverRunningAtStart = true; - } else if (retval == 0) { - logg->logMessage("Driver already mounted at startup"); - driverRunningAtStart = driverMountedAtStart = true; - } else { - char command[256]; // arbitrarily large amount - - // Is the driver co-located in the same directory? - if (util->getApplicationFullPath(command, sizeof(command)) != 0) { // allow some buffer space - logg->logMessage("Unable to determine the full path of gatord, the cwd will be used"); - } - strcat(command, "gator.ko"); - if (access(command, F_OK) == -1) { - logg->logError(__FILE__, __LINE__, "Unable to locate gator.ko driver:\n >>> gator.ko should be co-located with gatord in the same directory\n >>> OR insmod gator.ko prior to launching gatord"); - handleException(); - } - - // Load driver - strcpy(command, "insmod "); - util->getApplicationFullPath(&command[7], sizeof(command) - 64); // allow some buffer space - strcat(command, "gator.ko >/dev/null 2>&1"); - - if (system(command) != 0) { - logg->logMessage("Unable to load gator.ko driver with command: %s", command); - logg->logError(__FILE__, __LINE__, "Unable to load (insmod) gator.ko driver:\n >>> gator.ko must be built against the current kernel version & configuration\n >>> See dmesg for more details"); - handleException(); - } - - if (mountGatorFS() == -1) { - logg->logError(__FILE__, __LINE__, "Unable to mount the gator filesystem needed for profiling."); - handleException(); - } - } - - return 0; -} - -int shutdownFilesystem() { - if (driverMountedAtStart == false) - umount("/dev/gator"); - if (driverRunningAtStart == false) - if (system("rmmod gator >/dev/null 2>&1") != 0) - return -1; - - return 0; // success -} - -struct cmdline_t parseCommandLine(int argc, char** argv) { - struct cmdline_t cmdline; - cmdline.port = 8080; - cmdline.sessionXML = NULL; - int c; - - while ((c = getopt (argc, argv, "hvp:s:c:")) != -1) { - switch(c) { - case 'p': - cmdline.port = strtol(optarg, NULL, 10); - break; - case 's': - cmdline.sessionXML = optarg; - break; - case 'c': - gSessionData->configurationXMLPath = optarg; - break; - case 'h': - case '?': - logg->logError(__FILE__, __LINE__, - "Streamline gatord version %d. All parameters are optional:\n" - "-p port_number\tport upon which the server listens; default is 8080\n" - "-s session_xml\tpath and filename of a session xml used for local capture\n" - "-c config_xml\tpath and filename of the configuration.xml to use\n" - "-v\t\tversion information\n" - "-h\t\tthis help page\n", PROTOCOL_VERSION); - handleException(); - break; - case 'v': - logg->logError(__FILE__, __LINE__, "Streamline gatord version %d", PROTOCOL_VERSION); - handleException(); - break; - } - } - - // Error checking - if (cmdline.port != 8080 && cmdline.sessionXML != NULL) { - logg->logError(__FILE__, __LINE__, "Only a port or a session xml can be specified, not both"); - handleException(); - } - - if (optind < argc) { - logg->logError(__FILE__, __LINE__, "Unknown argument: %s. Use '-h' for help.", argv[optind]); - handleException(); - } - - return cmdline; -} - -// Gator data flow: collector -> collector fifo -> sender -int main(int argc, char** argv, char *envp[]) { - gSessionData = new SessionData(); // Global data class - logg = new Logging(DEBUG); // Set up global thread-safe logging - util = new OlyUtility(); // Set up global utility class - - prctl(PR_SET_NAME, (unsigned int)&"gatord-main", 0, 0, 0); - pthread_mutex_init(&numSessions_mutex, NULL); - - signal(SIGINT, handler); - signal(SIGTERM, handler); - signal(SIGABRT, handler); - - // Set to high priority - if (setpriority(PRIO_PROCESS, syscall(__NR_gettid), -19) == -1) - logg->logMessage("setpriority() failed"); - - // Initialize session data - gSessionData->initialize(); - - // Parse the command line parameters - struct cmdline_t cmdline = parseCommandLine(argc, argv); - - // Call before setting up the SIGCHLD handler, as system() spawns child processes - setupFilesystem(); - - // Handle child exit codes - signal(SIGCHLD, child_exit); - - // Ignore the SIGPIPE signal so that any send to a broken socket will return an error code instead of asserting a signal - // Handling the error at the send function call is much easier than trying to do anything intelligent in the sig handler - signal(SIGPIPE, SIG_IGN); - - // If the command line argument is a session xml file, no need to open a socket - if (cmdline.sessionXML) { - child = new Child(cmdline.sessionXML); - child->run(); - delete child; - } else { - socket = new OlySocket(cmdline.port, true); - // Forever loop, can be exited via a signal or exception - while (1) { - logg->logMessage("Waiting on connection..."); - socket->acceptConnection(); - - int pid = fork(); - if (pid < 0) { - // Error - logg->logError(__FILE__, __LINE__, "Fork process failed. Please power cycle the target device if this error persists."); - } else if (pid == 0) { - // Child - socket->closeServerSocket(); - child = new Child(socket, numSessions + 1); - child->run(); - delete child; - exit(0); - } else { - // Parent - socket->closeSocket(); - - pthread_mutex_lock(&numSessions_mutex); - numSessions++; - pthread_mutex_unlock(&numSessions_mutex); - - // Maximum number of connections is 2 - int wait = 0; - while (numSessions > 1) { - // Throttle until one of the children exits before continuing to accept another socket connection - logg->logMessage("%d sessions active!", numSessions); - if (wait++ >= 10) { // Wait no more than 10 seconds - // Kill last created child - kill(pid, SIGALRM); - break; - } - sleep(1); - } - } - } - } - - cleanUp(); - return 0; -} diff --git a/drivers/gator/driver/Kconfig b/drivers/gator/driver/Kconfig deleted file mode 100644 index 3b685ad9963..00000000000 --- a/drivers/gator/driver/Kconfig +++ /dev/null @@ -1,7 +0,0 @@ -config GATOR - tristate "Gator module for ARM's Streamline Performance Analyzer" - default m - depends on GENERIC_TRACER || TRACING - depends on PROFILING - depends on HIGH_RES_TIMERS - depends on LOCAL_TIMERS || !(ARM && SMP) diff --git a/drivers/gator/driver/Makefile b/drivers/gator/driver/Makefile deleted file mode 100644 index d6dfeebf102..00000000000 --- a/drivers/gator/driver/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -ifneq ($(KERNELRELEASE),) - -# Uncomment the following line to enable kernel stack unwinding within gator, or update gator_backtrace.c -# EXTRA_CFLAGS += -DGATOR_KERNEL_STACK_UNWINDING - -obj-$(CONFIG_GATOR) := gator.o - -gator-y := gator_main.o \ - gator_events_irq.o \ - gator_events_sched.o \ - gator_events_net.o \ - gator_events_block.o \ - gator_events_meminfo.o \ - gator_events_power.o \ - gator_events_perf_pmu.o - -gator-y += gator_events_mmaped.o - -ifneq ($(GATOR_WITH_MALI_SUPPORT),) -ifeq ($(GATOR_WITH_MALI_SUPPORT),MALI_T6xx) -gator-y += gator_events_mali_t6xx.o -else -gator-y += gator_events_mali.o -endif -EXTRA_CFLAGS += -DMALI_SUPPORT=$(GATOR_WITH_MALI_SUPPORT) -endif - -gator-$(CONFIG_ARM) += gator_events_armv6.o \ - gator_events_armv7.o \ - gator_events_l2c-310.o \ - gator_events_scorpion.o - -$(obj)/gator_main.o: gator_events.h - -clean-files := gator_events.h - - chk_events.h = : - quiet_chk_events.h = echo ' CHK $@' -silent_chk_events.h = : -gator_events.h: FORCE - @$($(quiet)chk_events.h) - $(Q)cd $(srctree)/$(src) ; $(CONFIG_SHELL) gator_events.sh $(objtree)/$(obj)/$@ - -else - -all: - @echo - @echo "usage:" - @echo " make -C M=\`pwd\` ARCH=arm CROSS_COMPILE=<...> modules" - @echo - $(error) - -clean: - rm -f *.o .*.cmd gator_events.h modules.order Module.symvers gator.ko gator.mod.c - -endif diff --git a/drivers/gator/driver/gator.h b/drivers/gator/driver/gator.h deleted file mode 100644 index a7a323c3fae..00000000000 --- a/drivers/gator/driver/gator.h +++ /dev/null @@ -1,99 +0,0 @@ -/** - * 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. - */ - -#ifndef GATOR_H_ -#define GATOR_H_ - -#include -#include -#include -#include - -#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_NO_PERF_SUPPORT (!(GATOR_PERF_SUPPORT)) -#define GATOR_CPU_FREQ_SUPPORT (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) && defined(CONFIG_CPU_FREQ) - -// cpu ids -#define ARM1136 0xb36 -#define ARM1156 0xb56 -#define ARM1176 0xb76 -#define ARM11MPCORE 0xb02 -#define CORTEX_A5 0xc05 -#define CORTEX_A7 0xc07 -#define CORTEX_A8 0xc08 -#define CORTEX_A9 0xc09 -#define CORTEX_A15 0xc0f -#define SCORPION 0x00f -#define SCORPIONMP 0x02d -#define KRAITSIM 0x049 -#define KRAIT 0x04d - -/****************************************************************************** - * Filesystem - ******************************************************************************/ -int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root, - char const *name, const struct file_operations *fops, int perm); - -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); - -int gatorfs_create_ro_ulong(struct super_block *sb, struct dentry *root, - char const *name, unsigned long *val); - -void gator_op_create_files(struct super_block *sb, struct dentry *root); - -/****************************************************************************** - * Tracepoints - ******************************************************************************/ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) -# error Kernels prior to 2.6.32 not supported -#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) -# define GATOR_DEFINE_PROBE(probe_name, proto) \ - static void probe_##probe_name(PARAMS(proto)) -# define GATOR_REGISTER_TRACE(probe_name) \ - register_trace_##probe_name(probe_##probe_name) -# define GATOR_UNREGISTER_TRACE(probe_name) \ - unregister_trace_##probe_name(probe_##probe_name) -#else -# define GATOR_DEFINE_PROBE(probe_name, proto) \ - static void probe_##probe_name(void *data, PARAMS(proto)) -# define GATOR_REGISTER_TRACE(probe_name) \ - register_trace_##probe_name(probe_##probe_name, NULL) -# define GATOR_UNREGISTER_TRACE(probe_name) \ - unregister_trace_##probe_name(probe_##probe_name, NULL) -#endif - -/****************************************************************************** - * 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); - struct list_head list; -}; - -#define gator_events_init(initfn) \ - static inline int __gator_events_init_test(void) \ - { return initfn(); } - -int gator_events_install(struct gator_interface *interface); -int gator_events_get_key(void); -extern u32 gator_cpuid(void); - -#endif // GATOR_H_ diff --git a/drivers/gator/driver/gator_annotate.c b/drivers/gator/driver/gator_annotate.c deleted file mode 100644 index 36a921cdd25..00000000000 --- a/drivers/gator/driver/gator_annotate.c +++ /dev/null @@ -1,181 +0,0 @@ -/** - * 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 -#include -#include -#include -#include -#include -#include - -#define ANNOTATE_SIZE (16*1024) -static DEFINE_SPINLOCK(annotate_lock); -static char *annotateBuf; -static char *annotateBuf0; -static char *annotateBuf1; -static int annotatePos; -static int annotateSel; -static bool collect_annotations = false; - -static ssize_t annotate_write(struct file *file, char const __user *buf, size_t count, loff_t *offset) -{ - char tempBuffer[512]; - int remaining, size; - uint32_t tid; - - if (*offset) - return -EINVAL; - - // determine size to capture - size = count < sizeof(tempBuffer) ? count : sizeof(tempBuffer); - - // note: copy may be for naught if remaining is zero, but better to do the copy outside of the spinlock - if (file == NULL) { - // copy from kernel - memcpy(tempBuffer, buf, size); - - // set the thread id to the kernel thread, not the current thread - tid = -1; - } else { - // copy from user space - if (copy_from_user(tempBuffer, buf, size) != 0) - return -EINVAL; - tid = current->pid; - } - - // synchronize shared variables annotateBuf and annotatePos - spin_lock(&annotate_lock); - if (collect_annotations && annotateBuf) { - remaining = ANNOTATE_SIZE - annotatePos - 256; // pad for headers and release - size = size < remaining ? size : remaining; - if (size > 0) { - uint64_t time = gator_get_time(); - uint32_t cpuid = smp_processor_id(); - int pos = annotatePos; - pos += gator_write_packed_int(&annotateBuf[pos], tid); - pos += gator_write_packed_int64(&annotateBuf[pos], time); - pos += gator_write_packed_int(&annotateBuf[pos], cpuid); - pos += gator_write_packed_int(&annotateBuf[pos], size); - memcpy(&annotateBuf[pos], tempBuffer, size); - annotatePos = pos + size; - } - } - spin_unlock(&annotate_lock); - - if (size <= 0) { - wake_up(&gator_buffer_wait); - return 0; - } - - // return the number of bytes written - return size; -} - -#include "gator_annotate_kernel.c" - -static int annotate_release(struct inode *inode, struct file *file) -{ - int remaining = ANNOTATE_SIZE - annotatePos; - if (remaining < 16) { - return -EFAULT; - } - - spin_lock(&annotate_lock); - if (annotateBuf) { - uint32_t tid = current->pid; - int pos = annotatePos; - pos += gator_write_packed_int(&annotateBuf[pos], tid); - pos += gator_write_packed_int64(&annotateBuf[pos], 0); // time - pos += gator_write_packed_int(&annotateBuf[pos], 0); // cpuid - pos += gator_write_packed_int(&annotateBuf[pos], 0); // size - annotatePos = pos; - } - spin_unlock(&annotate_lock); - - return 0; -} - -static const struct file_operations annotate_fops = { - .write = annotate_write, - .release = annotate_release -}; - -static int gator_annotate_create_files(struct super_block *sb, struct dentry *root) -{ - annotateBuf = NULL; - return gatorfs_create_file_perm(sb, root, "annotate", &annotate_fops, 0666); -} - -static int gator_annotate_init(void) -{ - annotateBuf0 = kmalloc(ANNOTATE_SIZE, GFP_KERNEL); - annotateBuf1 = kmalloc(ANNOTATE_SIZE, GFP_KERNEL); - if (!annotateBuf0 || !annotateBuf1) - return -1; - return 0; -} - -static int gator_annotate_start(void) -{ - annotateSel = 0; - annotatePos = 1; - annotateBuf = annotateBuf0; - annotateBuf[0] = FRAME_ANNOTATE; - collect_annotations = true; - return 0; -} - -static void gator_annotate_stop(void) -{ - collect_annotations = false; -} - -static void gator_annotate_shutdown(void) -{ - spin_lock(&annotate_lock); - annotateBuf = NULL; - spin_unlock(&annotate_lock); -} - -static void gator_annotate_exit(void) -{ - spin_lock(&annotate_lock); - kfree(annotateBuf0); - kfree(annotateBuf1); - annotateBuf = annotateBuf0 = annotateBuf1 = NULL; - spin_unlock(&annotate_lock); -} - -static int gator_annotate_ready(void) -{ - return annotatePos > 1 && annotateBuf; -} - -static int gator_annotate_read(char **buffer) -{ - int len; - - if (!gator_annotate_ready()) - return 0; - - annotateSel = !annotateSel; - - if (buffer) - *buffer = annotateBuf; - - spin_lock(&annotate_lock); - len = annotatePos; - annotateBuf = annotateSel ? annotateBuf1 : annotateBuf0; - annotateBuf[0] = FRAME_ANNOTATE; - annotatePos = 1; - spin_unlock(&annotate_lock); - - return len; -} diff --git a/drivers/gator/driver/gator_annotate_kernel.c b/drivers/gator/driver/gator_annotate_kernel.c deleted file mode 100644 index ffab08795b7..00000000000 --- a/drivers/gator/driver/gator_annotate_kernel.c +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Copyright (C) ARM Limited 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. - * - */ - -static void kannotate_write(char* ptr, unsigned int size) -{ - int retval; - int pos = 0; - loff_t offset = 0; - while (pos < size) { - retval = annotate_write(NULL, &ptr[pos], size - pos, &offset); - if (retval < 0) { - printk(KERN_WARNING "gator: kannotate_write failed with return value %d\n", retval); - return; - } - pos += retval; - } -} - -// String annotation -void gator_annotate(char* string) -{ - kannotate_write(string, strlen(string) + 1); -} -EXPORT_SYMBOL(gator_annotate); - -// String annotation with color -void gator_annotate_color(int color, char* string) -{ - kannotate_write((char*)&color, sizeof(color)); - kannotate_write(string, strlen(string) + 1); -} -EXPORT_SYMBOL(gator_annotate_color); - -// Terminate an annotation -void gator_annotate_end(void) -{ - char nul = 0; - kannotate_write(&nul, sizeof(nul)); -} -EXPORT_SYMBOL(gator_annotate_end); - -// Image annotation with optional string -void gator_annotate_visual(char* data, unsigned int length, char* string) -{ - long long visual_annotation = 0x011c | (strlen(string) << 16) | ((long long)length << 32); - kannotate_write((char*)&visual_annotation, 8); - kannotate_write(string, strlen(string)); - kannotate_write(data, length); -} -EXPORT_SYMBOL(gator_annotate_visual); - -// Marker annotation -void gator_annotate_marker(void) -{ - int marker_annotation = 0x00021c; - kannotate_write((char*)&marker_annotation, 3); -} -EXPORT_SYMBOL(gator_annotate_marker); - -// Marker annotation with a string -void gator_annotate_marker_str(char* string) -{ - int marker_annotation = 0x021c; - kannotate_write((char*)&marker_annotation, 2); - kannotate_write(string, strlen(string) + 1); -} -EXPORT_SYMBOL(gator_annotate_marker_str); - -// Marker annotation with a color -void gator_annotate_marker_color(int color) -{ - long long marker_annotation = (0x021c | ((long long)color << 16)) & 0x0000ffffffffffffLL; - kannotate_write((char*)&marker_annotation, 7); -} -EXPORT_SYMBOL(gator_annotate_marker_color); - -// Marker annotationw ith a string and color -void gator_annotate_marker_color_str(int color, char* string) -{ - long long marker_annotation = 0x021c | ((long long)color << 16); - kannotate_write((char*)&marker_annotation, 6); - kannotate_write(string, strlen(string) + 1); -} -EXPORT_SYMBOL(gator_annotate_marker_color_str); diff --git a/drivers/gator/driver/gator_backtrace.c b/drivers/gator/driver/gator_backtrace.c deleted file mode 100644 index 26503ef0a55..00000000000 --- a/drivers/gator/driver/gator_backtrace.c +++ /dev/null @@ -1,116 +0,0 @@ -/** - * 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. - * - */ - -/* - * EABI backtrace stores {fp,lr} on the stack. - */ -struct frame_tail_eabi { - unsigned long fp; // points to prev_lr - unsigned long lr; -}; - -static void arm_backtrace_eabi(int cpu, int buftype, struct pt_regs * const regs, unsigned int depth) -{ -#if defined(__arm__) - struct frame_tail_eabi *tail; - struct frame_tail_eabi *next; - struct frame_tail_eabi *ptrtail; - struct frame_tail_eabi buftail; - unsigned long fp = regs->ARM_fp; - unsigned long sp = regs->ARM_sp; - unsigned long lr = regs->ARM_lr; - int is_user_mode = user_mode(regs); - - if (!is_user_mode) { - return; - } - - /* entry preamble may not have executed */ - gator_add_trace(cpu, buftype, lr); - - /* check tail is valid */ - if (fp == 0 || fp < sp) { - return; - } - - tail = (struct frame_tail_eabi *)(fp - 4); - - 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; - if (__copy_from_user_inatomic(&buftail, tail, sizeof(struct frame_tail_eabi))) - return; - ptrtail = &buftail; - - lr = ptrtail[0].lr; - gator_add_trace(cpu, buftype, lr); - - /* frame pointers should progress back up the stack, towards higher addresses */ - next = (struct frame_tail_eabi *)(lr - 4); - if (tail >= next || lr == 0) { - fp = ptrtail[0].fp; - next = (struct frame_tail_eabi *)(fp - 4); - /* check tail is valid */ - if (tail >= next || fp == 0) { - return; - } - } - - tail = next; - } -#endif -} - -#if defined(__arm__) -static DEFINE_PER_CPU(int, backtrace_buffer); -static int report_trace(struct stackframe *frame, void *d) -{ - struct module *mod; - unsigned int *depth = d, addr = frame->pc, cookie = NO_COOKIE, cpu = smp_processor_id(); - - if (*depth) { - mod = __module_address(addr); - if (mod) { - cookie = get_cookie(cpu, per_cpu(backtrace_buffer, cpu), current, NULL, mod, true); - addr = addr - (unsigned long)mod->module_core; - } - gator_buffer_write_packed_int(cpu, per_cpu(backtrace_buffer, cpu), addr & ~1); - gator_buffer_write_packed_int(cpu, per_cpu(backtrace_buffer, cpu), cookie); - (*depth)--; - } - - return *depth == 0; -} -#endif - -// 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, int buftype, struct pt_regs * const regs) -{ -#if defined(__arm__) -#ifdef GATOR_KERNEL_STACK_UNWINDING - int depth = gator_backtrace_depth; -#else - int depth = 1; -#endif - struct stackframe frame; - if (depth == 0) - depth = 1; - frame.fp = regs->ARM_fp; - frame.sp = regs->ARM_sp; - frame.lr = regs->ARM_lr; - frame.pc = regs->ARM_pc; - per_cpu(backtrace_buffer, cpu) = buftype; - walk_stackframe(&frame, report_trace, &depth); -#else - gator_buffer_write_packed_int(cpu, buftype, PC_REG & ~1); - gator_buffer_write_packed_int(cpu, buftype, NO_COOKIE); -#endif -} diff --git a/drivers/gator/driver/gator_cookies.c b/drivers/gator/driver/gator_cookies.c deleted file mode 100644 index 1beb34f5170..00000000000 --- a/drivers/gator/driver/gator_cookies.c +++ /dev/null @@ -1,403 +0,0 @@ -/** - * 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. - * - */ - -#define COOKIEMAP_ENTRIES 1024 /* must be power of 2 */ -#define TRANSLATE_SIZE 256 -#define MAX_COLLISIONS 2 - -static uint32_t *gator_crc32_table; -static uint32_t translate_buffer_mask; - -static DEFINE_PER_CPU(char *, translate_text); -static DEFINE_PER_CPU(uint32_t, cookie_next_key); -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(unsigned int *, translate_buffer); - -static inline uint32_t get_cookie(int cpu, int buftype, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt); -static void wq_cookie_handler(struct work_struct *unused); -DECLARE_WORK(cookie_work, wq_cookie_handler); - -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); - return cookiecode * MAX_COLLISIONS; -} - -static uint32_t gator_chksum_crc32(char *data) -{ - register unsigned long crc; - unsigned char *block = data; - int i, length = strlen(data); - - crc = 0xFFFFFFFF; - for (i = 0; i < length; i++) { - crc = ((crc >> 8) & 0x00FFFFFF) ^ gator_crc32_table[(crc ^ *block++) & 0xFF]; - } - - return (crc ^ 0xFFFFFFFF); -} - -/* - * Exists - * Pre: [0][1][v][3]..[n-1] - * Post: [v][0][1][3]..[n-1] - */ -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); - uint64_t *keys = &(per_cpu(cookie_keys, cpu)[cookiecode]); - uint32_t *values = &(per_cpu(cookie_values, cpu)[cookiecode]); - - // Can be called from interrupt handler or from work queue - local_irq_save(flags); - for (x = 0; x < MAX_COLLISIONS; x++) { - if (keys[x] == key) { - uint32_t value = values[x]; - for (; x > 0; x--) { - keys[x] = keys[x-1]; - values[x] = values[x-1]; - } - keys[0] = key; - values[0] = value; - retval = value; - break; - } - } - local_irq_restore(flags); - - return retval; -} - -/* - * Add - * Pre: [0][1][2][3]..[n-1] - * Post: [v][0][1][2]..[n-2] - */ -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]; - } - keys[0] = key; - values[0] = value; -} - -static void translate_buffer_write_int(int cpu, unsigned int x) -{ - per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_write, cpu)++] = x; - per_cpu(translate_buffer_write, cpu) &= translate_buffer_mask; -} - -static unsigned int translate_buffer_read_int(int cpu) -{ - unsigned int value = per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_read, cpu)++]; - per_cpu(translate_buffer_read, cpu) &= translate_buffer_mask; - return value; -} - -static void wq_cookie_handler(struct work_struct *unused) -{ - struct task_struct *task; - struct vm_area_struct *vma; - int cpu = smp_processor_id(); - unsigned int cookie, commit; - - mutex_lock(&start_mutex); - - if (gator_started != 0) { - commit = per_cpu(translate_buffer_write, cpu); - while (per_cpu(translate_buffer_read, cpu) != commit) { - task = (struct task_struct *)translate_buffer_read_int(cpu); - vma = (struct vm_area_struct *)translate_buffer_read_int(cpu); - cookie = get_cookie(cpu, TIMER_BUF, task, vma, NULL, false); - } - } - - mutex_unlock(&start_mutex); -} - -// 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) -{ - void *maddr; - unsigned int len; - unsigned long addr; - struct mm_struct *mm; - struct page *page = NULL; - struct vm_area_struct *page_vma; - int bytes, offset, retval = 0, ptr; - 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) { - // Check if already in buffer - ptr = per_cpu(translate_buffer_read, cpu); - while (ptr != per_cpu(translate_buffer_write, cpu)) { - if (per_cpu(translate_buffer, cpu)[ptr] == (int)task) - goto out; - ptr = (ptr + 2) & translate_buffer_mask; - } - - translate_buffer_write_int(cpu, (unsigned int)task); - translate_buffer_write_int(cpu, (unsigned int)vma); - schedule_work(&cookie_work); - goto out; - } - - mm = get_task_mm(task); - if (!mm) - goto out; - if (!mm->arg_end) - goto outmm; - addr = mm->arg_start; - len = mm->arg_end - mm->arg_start; - - if (len > TRANSLATE_SIZE) - len = TRANSLATE_SIZE; - - down_read(&mm->mmap_sem); - while (len) { - if (get_user_pages(task, mm, addr, 1, 0, 1, &page, &page_vma) <= 0) - goto outsem; - - maddr = kmap(page); - offset = addr & (PAGE_SIZE-1); - bytes = len; - if (bytes > PAGE_SIZE - offset) - bytes = PAGE_SIZE - offset; - - copy_from_user_page(page_vma, page, addr, buf, maddr + offset, bytes); - - kunmap(page); // release page allocated by get_user_pages() - page_cache_release(page); - - len -= bytes; - buf += bytes; - addr += bytes; - - *text = per_cpu(translate_text, cpu); - retval = 1; - } - - // On app_process startup, /proc/pid/cmdline is initially "zygote" then "" but changes after an initial startup period - if (strcmp(*text, "zygote") == 0 || strcmp(*text, "") == 0) - retval = 0; - -outsem: - up_read(&mm->mmap_sem); -outmm: - mmput(mm); -out: - return retval; -} - -static inline uint32_t get_cookie(int cpu, int buftype, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt) -{ - 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; - - cookie = cookiemap_exists(key); - if (cookie) { - return cookie; - } - - if (strcmp(text, "app_process") == 0 && !mod) { - if (!translate_app_process(&text, cpu, task, vma, in_interrupt)) - return INVALID_COOKIE; - } - - // Can be called from interrupt handler or from work queue or from scheduler trace - local_irq_save(flags); - - cookie = INVALID_COOKIE; - if (buffer_check_space(cpu, buftype, strlen(text) + 2 * MAXSIZE_PACK32)) { - cookie = per_cpu(cookie_next_key, cpu) += nr_cpu_ids; - cookiemap_add(key, cookie); - - gator_buffer_write_packed_int(cpu, buftype, MESSAGE_COOKIE); - gator_buffer_write_packed_int(cpu, buftype, cookie); - gator_buffer_write_string(cpu, buftype, text); - } - - local_irq_restore(flags); - - return cookie; -} - -static int get_exec_cookie(int cpu, int buftype, struct task_struct *task) -{ - unsigned long cookie = NO_COOKIE; - struct mm_struct *mm = task->mm; - struct vm_area_struct *vma; - - if (!mm) - return 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, buftype, task, vma, NULL, true); - break; - } - - return cookie; -} - -static unsigned long get_address_cookie(int cpu, int buftype, struct task_struct *task, unsigned long addr, off_t *offset) -{ - unsigned long cookie = NO_COOKIE; - struct mm_struct *mm = task->mm; - struct vm_area_struct *vma; - - if (!mm) - return cookie; - - for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) { - if (addr < vma->vm_start || addr >= vma->vm_end) - continue; - - if (vma->vm_file) { - cookie = get_cookie(cpu, buftype, task, vma, NULL, true); - *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - vma->vm_start; - } else { - /* must be an anonymous map */ - *offset = addr; - } - - break; - } - - if (!vma) - cookie = INVALID_COOKIE; - - return cookie; -} - -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 - 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); - if (!per_cpu(cookie_keys, cpu)) { - err = -ENOMEM; - goto cookie_setup_error; - } - 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); - 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) = (unsigned int *)kmalloc(translate_buffer_size, GFP_KERNEL); - if (!per_cpu(translate_buffer, cpu)) { - err = -ENOMEM; - goto cookie_setup_error; - } - - per_cpu(translate_buffer_write, cpu) = 0; - per_cpu(translate_buffer_read, cpu) = 0; - - per_cpu(translate_text, cpu) = (char *)kmalloc(TRANSLATE_SIZE, GFP_KERNEL); - if (!per_cpu(translate_text, cpu)) { - err = -ENOMEM; - goto cookie_setup_error; - } - } - - // build CRC32 table - poly = 0x04c11db7; - 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--) { - if (crc & 1) { - crc = (crc >> 1) ^ poly; - } else { - crc >>= 1; - } - } - gator_crc32_table[i] = crc; - } - -cookie_setup_error: - return err; -} - -static void cookies_release(void) -{ - int cpu; - - for_each_present_cpu(cpu) { - kfree(per_cpu(cookie_keys, cpu)); - per_cpu(cookie_keys, cpu) = NULL; - - kfree(per_cpu(cookie_values, cpu)); - per_cpu(cookie_values, cpu) = NULL; - - kfree(per_cpu(translate_buffer, cpu)); - per_cpu(translate_buffer, cpu) = NULL; - per_cpu(translate_buffer_read, cpu) = 0; - per_cpu(translate_buffer_write, cpu) = 0; - - kfree(per_cpu(translate_text, cpu)); - per_cpu(translate_text, cpu) = NULL; - } - - kfree(gator_crc32_table); - gator_crc32_table = NULL; -} diff --git a/drivers/gator/driver/gator_ebs.c b/drivers/gator/driver/gator_ebs.c deleted file mode 100644 index 8c2997c57da..00000000000 --- a/drivers/gator/driver/gator_ebs.c +++ /dev/null @@ -1,192 +0,0 @@ -/** - * Copyright (C) ARM Limited 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. - * - */ - -#if defined(__arm__) && (GATOR_PERF_PMU_SUPPORT) -#include -#include -#include - -#include - -extern int pmnc_counters; -extern int ccnt; -extern unsigned long pmnc_enabled[]; -extern unsigned long pmnc_event[]; -extern unsigned long pmnc_count[]; -extern unsigned long pmnc_key[]; - -static DEFINE_PER_CPU(struct perf_event *, pevent); -static DEFINE_PER_CPU(struct perf_event_attr *, pevent_attr); -static DEFINE_PER_CPU(int, key); -static DEFINE_PER_CPU(unsigned int, prev_value); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) -static void ebs_overflow_handler(struct perf_event *event, int unused, struct perf_sample_data *data, struct pt_regs *regs) -#else -static void ebs_overflow_handler(struct perf_event *event, struct perf_sample_data *data, struct pt_regs *regs) -#endif -{ - unsigned int value, delta, cpu = smp_processor_id(), buftype = EVENT_BUF; - - if (event != per_cpu(pevent, cpu)) - return; - - if (buffer_check_space(cpu, buftype, 5 * MAXSIZE_PACK32 + MAXSIZE_PACK64)) { - value = local64_read(&event->count); - delta = value - per_cpu(prev_value, cpu); - per_cpu(prev_value, cpu) = value; - - // Counters header - gator_buffer_write_packed_int(cpu, buftype, MESSAGE_COUNTERS); // type - gator_buffer_write_packed_int64(cpu, buftype, gator_get_time()); // time - - // Output counter - gator_buffer_write_packed_int(cpu, buftype, 2); // length - gator_buffer_write_packed_int(cpu, buftype, per_cpu(key, cpu)); // key - gator_buffer_write_packed_int(cpu, buftype, delta); // delta - - // End Counters, length of zero - gator_buffer_write_packed_int(cpu, buftype, 0); - } - - // Output backtrace - if (buffer_check_space(cpu, buftype, gator_backtrace_depth * 2 * MAXSIZE_PACK32)) - gator_add_sample(cpu, buftype, regs); - - // Check and commit; commit is set to occur once buffer is 3/4 full - buffer_check(cpu, buftype); -} - -static void gator_event_sampling_online(void) -{ - int cpu = smp_processor_id(), buftype = EVENT_BUF; - - // read the counter and toss the invalid data, return zero instead - struct perf_event * ev = per_cpu(pevent, cpu); - if (ev != NULL && ev->state == PERF_EVENT_STATE_ACTIVE) { - ev->pmu->read(ev); - per_cpu(prev_value, cpu) = local64_read(&ev->count); - - // Counters header - gator_buffer_write_packed_int(cpu, buftype, MESSAGE_COUNTERS); // type - gator_buffer_write_packed_int64(cpu, buftype, gator_get_time()); // time - - // Output counter - gator_buffer_write_packed_int(cpu, buftype, 2); // length - gator_buffer_write_packed_int(cpu, buftype, per_cpu(key, cpu)); // key - gator_buffer_write_packed_int(cpu, buftype, 0); // delta - zero for initialization - - // End Counters, length of zero - gator_buffer_write_packed_int(cpu, buftype, 0); - } -} - -static void gator_event_sampling_online_dispatch(int cpu) -{ - struct perf_event * ev; - - if (!event_based_sampling) - return; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) - ev = per_cpu(pevent, cpu) = perf_event_create_kernel_counter(per_cpu(pevent_attr, cpu), cpu, 0, ebs_overflow_handler); -#else - ev = per_cpu(pevent, cpu) = perf_event_create_kernel_counter(per_cpu(pevent_attr, cpu), cpu, 0, ebs_overflow_handler, 0); -#endif - - if (IS_ERR(ev)) { - pr_err("gator: unable to start event-based-sampling"); - return; - } - - if (ev->state != PERF_EVENT_STATE_ACTIVE) { - pr_err("gator: unable to start event-based-sampling"); - perf_event_release_kernel(ev); - return; - } - - ev->pmu->read(ev); - per_cpu(prev_value, cpu) = local64_read(&ev->count); -} - -static void gator_event_sampling_offline_dispatch(int cpu) -{ - if (per_cpu(pevent, cpu)) { - perf_event_release_kernel(per_cpu(pevent, cpu)); - per_cpu(pevent, cpu) = NULL; - } -} - -static int gator_event_sampling_start(void) -{ - int cnt, event = 0, count = 0, ebs_key = 0, cpu; - - for_each_present_cpu(cpu) { - per_cpu(pevent, cpu) = NULL; - per_cpu(pevent_attr, cpu) = NULL; - } - - event_based_sampling = false; - for (cnt = 0; cnt < pmnc_counters; cnt++) { - if (pmnc_count[cnt] > 0) { - event_based_sampling = true; - event = pmnc_event[cnt]; - count = pmnc_count[cnt]; - ebs_key = pmnc_key[cnt]; - break; - } - } - - if (!event_based_sampling) - return 0; - - for_each_present_cpu(cpu) { - u32 size = sizeof(struct perf_event_attr); - per_cpu(pevent_attr, cpu) = kmalloc(size, GFP_KERNEL); - if (!per_cpu(pevent_attr, cpu)) - return -1; - - memset(per_cpu(pevent_attr, cpu), 0, size); - per_cpu(pevent_attr, cpu)->type = PERF_TYPE_RAW; - per_cpu(pevent_attr, cpu)->size = size; - per_cpu(pevent_attr, cpu)->config = event; - per_cpu(pevent_attr, cpu)->sample_period = count; - per_cpu(pevent_attr, cpu)->pinned = 1; - - // handle special case for ccnt - if (cnt == ccnt) { - per_cpu(pevent_attr, cpu)->type = PERF_TYPE_HARDWARE; - per_cpu(pevent_attr, cpu)->config = PERF_COUNT_HW_CPU_CYCLES; - } - - per_cpu(key, cpu) = ebs_key; - } - - return 0; -} - -static void gator_event_sampling_stop(void) -{ - int cpu; - - for_each_present_cpu(cpu) { - if (per_cpu(pevent_attr, cpu)) { - kfree(per_cpu(pevent_attr, cpu)); - per_cpu(pevent_attr, cpu) = NULL; - } - } -} - -#else -static void gator_event_sampling_online(void) {} -static void gator_event_sampling_online_dispatch(int cpu) {} -static void gator_event_sampling_offline_dispatch(int cpu) {} -static int gator_event_sampling_start(void) {return 0;} -static void gator_event_sampling_stop(void) {} -#endif diff --git a/drivers/gator/driver/gator_events.sh b/drivers/gator/driver/gator_events.sh deleted file mode 100644 index 5467dd6d17d..00000000000 --- a/drivers/gator/driver/gator_events.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -EVENTS=`grep gator_events_init *.c | sed 's/.\+gator_events_init(\(.\+\)).\+/\1/'` - -( - echo /\* This file is auto generated \*/ - echo - for EVENT in $EVENTS; do - echo __weak int $EVENT\(void\)\; - done - echo - echo static int \(*gator_events_list[]\)\(void\) = { - for EVENT in $EVENTS; do - echo \ $EVENT, - done - echo }\; -) > $1.tmp - -cmp -s $1 $1.tmp && rm $1.tmp || mv $1.tmp $1 diff --git a/drivers/gator/driver/gator_events_armv6.c b/drivers/gator/driver/gator_events_armv6.c deleted file mode 100644 index ef518987906..00000000000 --- a/drivers/gator/driver/gator_events_armv6.c +++ /dev/null @@ -1,244 +0,0 @@ -/** - * 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 "gator.h" - -// gator_events_perf_pmu.c is used if perf is supported -#if GATOR_NO_PERF_SUPPORT - -static const char *pmnc_name; - -/* - * Per-CPU PMCR - */ -#define PMCR_E (1 << 0) /* Enable */ -#define PMCR_P (1 << 1) /* Count reset */ -#define PMCR_C (1 << 2) /* Cycle counter reset */ -#define PMCR_OFL_PMN0 (1 << 8) /* Count reg 0 overflow */ -#define PMCR_OFL_PMN1 (1 << 9) /* Count reg 1 overflow */ -#define PMCR_OFL_CCNT (1 << 10) /* Cycle counter overflow */ - -#define PMN0 0 -#define PMN1 1 -#define CCNT 2 -#define CNTMAX (CCNT+1) - -static int pmnc_counters = 0; -static unsigned long pmnc_enabled[CNTMAX]; -static unsigned long pmnc_event[CNTMAX]; -static unsigned long pmnc_key[CNTMAX]; - -static DEFINE_PER_CPU(int[CNTMAX], perfPrev); -static DEFINE_PER_CPU(int[CNTMAX * 2], perfCnt); - -static inline void armv6_pmnc_write(u32 val) -{ - /* upper 4bits and 7, 11 are write-as-0 */ - val &= 0x0ffff77f; - asm volatile("mcr p15, 0, %0, c15, c12, 0" : : "r" (val)); -} - -static inline u32 armv6_pmnc_read(void) -{ - u32 val; - asm volatile("mrc p15, 0, %0, c15, c12, 0" : "=r" (val)); - return val; -} - -static void armv6_pmnc_reset_counter(unsigned int cnt) -{ - u32 val = 0; - switch (cnt) { - case CCNT: - asm volatile("mcr p15, 0, %0, c15, c12, 1" : : "r" (val)); - break; - case PMN0: - asm volatile("mcr p15, 0, %0, c15, c12, 2" : : "r" (val)); - break; - case PMN1: - asm volatile("mcr p15, 0, %0, c15, c12, 3" : : "r" (val)); - break; - } -} - -int gator_events_armv6_create_files(struct super_block *sb, struct dentry *root) -{ - struct dentry *dir; - int i; - - pmnc_counters = 3; - - for (i = PMN0; i <= CCNT; i++) { - char buf[40]; - if (i == CCNT) { - snprintf(buf, sizeof buf, "ARM_%s_ccnt", pmnc_name); - } else { - snprintf(buf, sizeof buf, "ARM_%s_cnt%d", pmnc_name, i); - } - 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]); - if (i != CCNT) { - gatorfs_create_ulong(sb, dir, "event", &pmnc_event[i]); - } - } - - return 0; -} - -static int gator_events_armv6_online(int** buffer) -{ - unsigned int cnt, len = 0, cpu = smp_processor_id(); - u32 pmnc; - - if (armv6_pmnc_read() & PMCR_E) { - armv6_pmnc_write(armv6_pmnc_read() & ~PMCR_E); - } - - /* 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); - - /* configure control register */ - for (pmnc = 0, cnt = PMN0; cnt <= CCNT; cnt++) { - unsigned long event; - - per_cpu(perfPrev, cpu)[cnt] = 0; - - if (!pmnc_enabled[cnt]) - continue; - - event = pmnc_event[cnt] & 255; - - // Set event (if destined for PMNx counters) - if (cnt == PMN0) { - pmnc |= event << 20; - } else if (cnt == PMN1) { - pmnc |= event << 12; - } - - // Reset counter - armv6_pmnc_reset_counter(cnt); - } - armv6_pmnc_write(pmnc | PMCR_E); - - // return zero values, no need to read as the counters were just reset - for (cnt = PMN0; cnt <= CCNT; cnt++) { - if (pmnc_enabled[cnt]) { - per_cpu(perfCnt, cpu)[len++] = pmnc_key[cnt]; - per_cpu(perfCnt, cpu)[len++] = 0; - } - } - - if (buffer) - *buffer = per_cpu(perfCnt, cpu); - - return len; -} - -static int gator_events_armv6_offline(int** buffer) -{ - unsigned int cnt; - - armv6_pmnc_write(armv6_pmnc_read() & ~PMCR_E); - for (cnt = PMN0; cnt <= CCNT; cnt++) { - armv6_pmnc_reset_counter(cnt); - } - - return 0; -} - -static void gator_events_armv6_stop(void) -{ - unsigned int cnt; - - for (cnt = PMN0; cnt <= CCNT; cnt++) { - pmnc_enabled[cnt] = 0; - pmnc_event[cnt] = 0; - } -} - -static int gator_events_armv6_read(int **buffer) -{ - int cnt, len = 0; - int cpu = smp_processor_id(); - - for (cnt = PMN0; cnt <= CCNT; cnt++) { - if (pmnc_enabled[cnt]) { - u32 value = 0; - switch (cnt) { - case CCNT: - asm volatile("mrc p15, 0, %0, c15, c12, 1" : "=r" (value)); - break; - case PMN0: - asm volatile("mrc p15, 0, %0, c15, c12, 2" : "=r" (value)); - break; - case PMN1: - asm volatile("mrc p15, 0, %0, c15, c12, 3" : "=r" (value)); - break; - } - armv6_pmnc_reset_counter(cnt); - if (value != per_cpu(perfPrev, cpu)[cnt]) { - per_cpu(perfPrev, cpu)[cnt] = value; - per_cpu(perfCnt, cpu)[len++] = pmnc_key[cnt]; - per_cpu(perfCnt, cpu)[len++] = value; - } - } - } - - if (buffer) - *buffer = per_cpu(perfCnt, cpu); - - return len; -} - -static struct gator_interface gator_events_armv6_interface = { - .create_files = gator_events_armv6_create_files, - .stop = gator_events_armv6_stop, - .online = gator_events_armv6_online, - .offline = gator_events_armv6_offline, - .read = gator_events_armv6_read, -}; - -int gator_events_armv6_init(void) -{ - unsigned int cnt; - - switch (gator_cpuid()) { - case ARM1136: - case ARM1156: - case ARM1176: - pmnc_name = "ARM11"; - break; - case ARM11MPCORE: - pmnc_name = "ARM11MPCore"; - break; - default: - return -1; - } - - for (cnt = PMN0; cnt <= CCNT; cnt++) { - pmnc_enabled[cnt] = 0; - pmnc_event[cnt] = 0; - pmnc_key[cnt] = gator_events_get_key(); - } - - return gator_events_install(&gator_events_armv6_interface); -} - -gator_events_init(gator_events_armv6_init); - -#else -int gator_events_armv6_init(void) -{ - return -1; -} -#endif diff --git a/drivers/gator/driver/gator_events_armv7.c b/drivers/gator/driver/gator_events_armv7.c deleted file mode 100644 index cdf450f1975..00000000000 --- a/drivers/gator/driver/gator_events_armv7.c +++ /dev/null @@ -1,320 +0,0 @@ -/** - * 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. - */ - -/* Disabling interrupts - * Many of the functions below disable interrupts via local_irq_save(). This disabling of interrupts is done to prevent any race conditions - * between multiple entities (e.g. hrtimer interrupts and event based interrupts) calling the same functions. As accessing the pmu involves - * several steps (disable, select, read, enable), these steps must be performed atomically. Normal synchronization routines cannot be used - * as these functions are being called from interrupt context. - */ - -#include "gator.h" - -// gator_events_perf_pmu.c is used if perf is supported -#if GATOR_NO_PERF_SUPPORT - -// Per-CPU PMNC: config reg -#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 */ - -// ccnt reg -#define CCNT_REG (1 << 31) - -#define CCNT 0 -#define CNT0 1 -#define CNTMAX (6+1) - -static const char *pmnc_name; -static int pmnc_counters; - -static unsigned long pmnc_enabled[CNTMAX]; -static unsigned long pmnc_event[CNTMAX]; -static unsigned long pmnc_key[CNTMAX]; - -static DEFINE_PER_CPU(int[CNTMAX], perfPrev); -static DEFINE_PER_CPU(int[CNTMAX * 2], perfCnt); - -inline void armv7_pmnc_write(u32 val) -{ - val &= PMNC_MASK; - asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (val)); -} - -inline u32 armv7_pmnc_read(void) -{ - u32 val; - asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val)); - return val; -} - -inline u32 armv7_ccnt_read(u32 reset_value) -{ - unsigned long flags; - u32 newval = -reset_value; - u32 den = CCNT_REG; - u32 val; - - 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, c12, 1" : : "r" (den)); // enable - local_irq_restore(flags); - - return val; -} - -inline u32 armv7_cntn_read(unsigned int cnt, u32 reset_value) -{ - unsigned long flags; - u32 newval = -reset_value; - u32 sel = (cnt - CNT0); - u32 den = 1 << sel; - u32 oldval; - - local_irq_save(flags); - 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, c12, 1" : : "r" (den)); // enable - local_irq_restore(flags); - - return oldval; -} - -static inline void armv7_pmnc_disable_interrupt(unsigned int cnt) -{ - u32 val = cnt ? (1 << (cnt - CNT0)) : (1 << 31); - asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (val)); -} - -inline u32 armv7_pmnc_reset_interrupt(void) -{ - // Get and reset overflow status flags - u32 flags; - asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (flags)); - flags &= 0x8000003f; - asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (flags)); - return flags; -} - -static inline u32 armv7_pmnc_enable_counter(unsigned int cnt) -{ - u32 val = cnt ? (1 << (cnt - CNT0)) : CCNT_REG; - asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val)); - return cnt; -} - -static inline u32 armv7_pmnc_disable_counter(unsigned int cnt) -{ - u32 val = cnt ? (1 << (cnt - CNT0)) : CCNT_REG; - asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val)); - return cnt; -} - -static inline int armv7_pmnc_select_counter(unsigned int cnt) -{ - u32 val = (cnt - CNT0); - asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val)); - return cnt; -} - -static inline void armv7_pmnc_write_evtsel(unsigned int cnt, u32 val) -{ - if (armv7_pmnc_select_counter(cnt) == cnt) { - asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val)); - } -} - -static int gator_events_armv7_create_files(struct super_block *sb, struct dentry *root) -{ - struct dentry *dir; - int i; - - for (i = 0; i < pmnc_counters; i++) { - char buf[40]; - 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); - } - 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]); - if (i > 0) { - gatorfs_create_ulong(sb, dir, "event", &pmnc_event[i]); - } - } - - return 0; -} - -static int gator_events_armv7_online(int** buffer) -{ - unsigned int cnt, len = 0, cpu = smp_processor_id(); - - if (armv7_pmnc_read() & PMNC_E) { - armv7_pmnc_write(armv7_pmnc_read() & ~PMNC_E); - } - - // Initialize & Reset PMNC: C bit and P bit - armv7_pmnc_write(PMNC_P | PMNC_C); - - // Reset overflow flags - armv7_pmnc_reset_interrupt(); - - for (cnt = CCNT; cnt < CNTMAX; cnt++) { - unsigned long event; - - per_cpu(perfPrev, cpu)[cnt] = 0; - - if (!pmnc_enabled[cnt]) - continue; - - // Disable counter - armv7_pmnc_disable_counter(cnt); - - event = pmnc_event[cnt] & 255; - - // Set event (if destined for PMNx counters), we don't need to set the event if it's a cycle count - if (cnt != CCNT) - armv7_pmnc_write_evtsel(cnt, event); - - armv7_pmnc_disable_interrupt(cnt); - - // Reset counter - cnt ? armv7_cntn_read(cnt, 0) : armv7_ccnt_read(0); - - // Enable counter - armv7_pmnc_enable_counter(cnt); - } - - // enable - armv7_pmnc_write(armv7_pmnc_read() | PMNC_E); - - // return zero values, no need to read as the counters were just reset - for (cnt = 0; cnt < pmnc_counters; cnt++) { - if (pmnc_enabled[cnt]) { - per_cpu(perfCnt, cpu)[len++] = pmnc_key[cnt]; - per_cpu(perfCnt, cpu)[len++] = 0; - } - } - - if (buffer) - *buffer = per_cpu(perfCnt, cpu); - - return len; -} - -static int gator_events_armv7_offline(int** buffer) -{ - // disbale all counters, including PMCCNTR; overflow IRQs will not be signaled - armv7_pmnc_write(armv7_pmnc_read() & ~PMNC_E); - - return 0; -} - -static void gator_events_armv7_stop(void) -{ - unsigned int cnt; - - for (cnt = CCNT; cnt < CNTMAX; cnt++) { - pmnc_enabled[cnt] = 0; - pmnc_event[cnt] = 0; - } -} - -static int gator_events_armv7_read(int **buffer) -{ - int cnt, len = 0; - int cpu = smp_processor_id(); - - for (cnt = 0; cnt < pmnc_counters; cnt++) { - if (pmnc_enabled[cnt]) { - int value; - if (cnt == CCNT) { - value = armv7_ccnt_read(0); - } else { - value = armv7_cntn_read(cnt, 0); - } - if (value != per_cpu(perfPrev, cpu)[cnt]) { - per_cpu(perfPrev, cpu)[cnt] = value; - per_cpu(perfCnt, cpu)[len++] = pmnc_key[cnt]; - per_cpu(perfCnt, cpu)[len++] = value; - } - } - } - - if (buffer) - *buffer = per_cpu(perfCnt, cpu); - - return len; -} - -static struct gator_interface gator_events_armv7_interface = { - .create_files = gator_events_armv7_create_files, - .stop = gator_events_armv7_stop, - .online = gator_events_armv7_online, - .offline = gator_events_armv7_offline, - .read = gator_events_armv7_read, -}; - -int gator_events_armv7_init(void) -{ - unsigned int cnt; - - switch (gator_cpuid()) { - case CORTEX_A5: - pmnc_name = "Cortex-A5"; - pmnc_counters = 2; - break; - case CORTEX_A7: - pmnc_name = "Cortex-A7"; - pmnc_counters = 4; - break; - case CORTEX_A8: - pmnc_name = "Cortex-A8"; - pmnc_counters = 4; - break; - case CORTEX_A9: - pmnc_name = "Cortex-A9"; - pmnc_counters = 6; - break; - case CORTEX_A15: - pmnc_name = "Cortex-A15"; - pmnc_counters = 6; - break; - default: - return -1; - } - - pmnc_counters++; // CNT[n] + CCNT - - for (cnt = CCNT; cnt < CNTMAX; cnt++) { - pmnc_enabled[cnt] = 0; - pmnc_event[cnt] = 0; - pmnc_key[cnt] = gator_events_get_key(); - } - - return gator_events_install(&gator_events_armv7_interface); -} - -gator_events_init(gator_events_armv7_init); - -#else -int gator_events_armv7_init(void) -{ - return -1; -} -#endif diff --git a/drivers/gator/driver/gator_events_block.c b/drivers/gator/driver/gator_events_block.c deleted file mode 100644 index f1bbbc83bfb..00000000000 --- a/drivers/gator/driver/gator_events_block.c +++ /dev/null @@ -1,171 +0,0 @@ -/** - * 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 "gator.h" -#include - -#define BLOCK_RQ_WR 0 -#define BLOCK_RQ_RD 1 - -#define BLOCK_TOTAL (BLOCK_RQ_RD+1) - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) -#define EVENTWRITE REQ_RW -#else -#define EVENTWRITE REQ_WRITE -#endif - -static ulong block_rq_wr_enabled; -static ulong block_rq_rd_enabled; -static ulong block_rq_wr_key; -static ulong block_rq_rd_key; -static DEFINE_PER_CPU(int[BLOCK_TOTAL], blockCnt); -static DEFINE_PER_CPU(int[BLOCK_TOTAL * 2], blockGet); -static DEFINE_PER_CPU(bool, new_data_avail); - -GATOR_DEFINE_PROBE(block_rq_complete, TP_PROTO(struct request_queue *q, struct request *rq)) -{ - unsigned long flags; - int write, size; - int cpu = smp_processor_id(); - - if (!rq) - return; - - write = rq->cmd_flags & EVENTWRITE; - size = rq->resid_len; - - if (!size) - return; - - // disable interrupts to synchronize with gator_events_block_read() - // spinlocks not needed since percpu buffers are used - local_irq_save(flags); - if (write) - per_cpu(blockCnt, cpu)[BLOCK_RQ_WR] += size; - else - per_cpu(blockCnt, cpu)[BLOCK_RQ_RD] += size; - local_irq_restore(flags); - - per_cpu(new_data_avail, cpu) = true; -} - -static int gator_events_block_create_files(struct super_block *sb, struct dentry *root) -{ - struct dentry *dir; - - /* block_complete_wr */ - dir = gatorfs_mkdir(sb, root, "Linux_block_rq_wr"); - if (!dir) { - return -1; - } - gatorfs_create_ulong(sb, dir, "enabled", &block_rq_wr_enabled); - gatorfs_create_ro_ulong(sb, dir, "key", &block_rq_wr_key); - - /* block_complete_rd */ - dir = gatorfs_mkdir(sb, root, "Linux_block_rq_rd"); - if (!dir) { - return -1; - } - gatorfs_create_ulong(sb, dir, "enabled", &block_rq_rd_enabled); - gatorfs_create_ro_ulong(sb, dir, "key", &block_rq_rd_key); - - return 0; -} - -static int gator_events_block_start(void) -{ - int cpu; - - for_each_present_cpu(cpu) - per_cpu(new_data_avail, cpu) = true; - - // register tracepoints - if (block_rq_wr_enabled || block_rq_rd_enabled) - if (GATOR_REGISTER_TRACE(block_rq_complete)) - goto fail_block_rq_exit; - pr_debug("gator: registered block event tracepoints\n"); - - return 0; - - // unregister tracepoints on error -fail_block_rq_exit: - pr_err("gator: block event tracepoints failed to activate, please verify that tracepoints are enabled in the linux kernel\n"); - - return -1; -} - -static void gator_events_block_stop(void) -{ - if (block_rq_wr_enabled || block_rq_rd_enabled) - GATOR_UNREGISTER_TRACE(block_rq_complete); - pr_debug("gator: unregistered block event tracepoints\n"); - - block_rq_wr_enabled = 0; - block_rq_rd_enabled = 0; -} - -static int gator_events_block_read(int **buffer) -{ - unsigned long flags; - int len, value, cpu, data = 0; - cpu = smp_processor_id(); - - if (per_cpu(new_data_avail, cpu) == false) - return 0; - - per_cpu(new_data_avail, cpu) = false; - - len = 0; - if (block_rq_wr_enabled) { - local_irq_save(flags); - value = per_cpu(blockCnt, cpu)[BLOCK_RQ_WR]; - per_cpu(blockCnt, cpu)[BLOCK_RQ_WR] = 0; - local_irq_restore(flags); - per_cpu(blockGet, cpu)[len++] = block_rq_wr_key; - per_cpu(blockGet, cpu)[len++] = value; - data += value; - } - if (block_rq_rd_enabled) { - local_irq_save(flags); - value = per_cpu(blockCnt, cpu)[BLOCK_RQ_RD]; - per_cpu(blockCnt, cpu)[BLOCK_RQ_RD] = 0; - local_irq_restore(flags); - per_cpu(blockGet, cpu)[len++] = block_rq_rd_key; - per_cpu(blockGet, cpu)[len++] = value; - data += value; - } - - if (data != 0) - per_cpu(new_data_avail, cpu) = true; - - if (buffer) - *buffer = per_cpu(blockGet, cpu); - - return len; -} - -static struct gator_interface gator_events_block_interface = { - .create_files = gator_events_block_create_files, - .start = gator_events_block_start, - .stop = gator_events_block_stop, - .read = gator_events_block_read, -}; - -int gator_events_block_init(void) -{ - block_rq_wr_enabled = 0; - block_rq_rd_enabled = 0; - - block_rq_wr_key = gator_events_get_key(); - block_rq_rd_key = gator_events_get_key(); - - return gator_events_install(&gator_events_block_interface); -} -gator_events_init(gator_events_block_init); diff --git a/drivers/gator/driver/gator_events_irq.c b/drivers/gator/driver/gator_events_irq.c deleted file mode 100644 index 59461b9799e..00000000000 --- a/drivers/gator/driver/gator_events_irq.c +++ /dev/null @@ -1,195 +0,0 @@ -/** - * 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 "gator.h" -#include - -#define HARDIRQ 0 -#define SOFTIRQ 1 -#define TOTALIRQ (SOFTIRQ+1) - -static ulong hardirq_enabled; -static ulong softirq_enabled; -static ulong hardirq_key; -static ulong softirq_key; -static DEFINE_PER_CPU(int[TOTALIRQ], irqCnt); -static DEFINE_PER_CPU(int[TOTALIRQ], irqPrev); -static DEFINE_PER_CPU(int[TOTALIRQ * 2], irqGet); - -GATOR_DEFINE_PROBE(irq_handler_exit, TP_PROTO(int irq, - struct irqaction *action, int ret)) -{ - unsigned long flags; - - // disable interrupts to synchronize with gator_events_irq_read() - // spinlocks not needed since percpu buffers are used - local_irq_save(flags); - per_cpu(irqCnt, smp_processor_id())[HARDIRQ]++; - local_irq_restore(flags); -} - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37) -GATOR_DEFINE_PROBE(softirq_exit, TP_PROTO(struct softirq_action *h, struct softirq_action *vec)) -#else -GATOR_DEFINE_PROBE(softirq_exit, TP_PROTO(unsigned int vec_nr)) -#endif -{ - unsigned long flags; - - // disable interrupts to synchronize with gator_events_irq_read() - // spinlocks not needed since percpu buffers are used - local_irq_save(flags); - per_cpu(irqCnt, smp_processor_id())[SOFTIRQ]++; - local_irq_restore(flags); -} - -static int gator_events_irq_create_files(struct super_block *sb, struct dentry *root) -{ - struct dentry *dir; - - /* irq */ - dir = gatorfs_mkdir(sb, root, "Linux_irq_irq"); - if (!dir) { - return -1; - } - gatorfs_create_ulong(sb, dir, "enabled", &hardirq_enabled); - gatorfs_create_ro_ulong(sb, dir, "key", &hardirq_key); - - /* soft irq */ - dir = gatorfs_mkdir(sb, root, "Linux_irq_softirq"); - if (!dir) { - return -1; - } - gatorfs_create_ulong(sb, dir, "enabled", &softirq_enabled); - gatorfs_create_ro_ulong(sb, dir, "key", &softirq_key); - - return 0; -} - -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 - - // synchronization with the irq_exit functions is not necessary as the values are being reset - if (hardirq_enabled) { - local_irq_save(flags); - per_cpu(irqCnt, cpu)[HARDIRQ] = 0; - local_irq_restore(flags); - per_cpu(irqPrev, cpu)[HARDIRQ] = 0; - per_cpu(irqGet, cpu)[len++] = hardirq_key; - per_cpu(irqGet, cpu)[len++] = 0; - } - - if (softirq_enabled) { - local_irq_save(flags); - per_cpu(irqCnt, cpu)[SOFTIRQ] = 0; - local_irq_restore(flags); - per_cpu(irqPrev, cpu)[SOFTIRQ] = 0; - per_cpu(irqGet, cpu)[len++] = softirq_key; - per_cpu(irqGet, cpu)[len++] = 0; - } - - if (buffer) - *buffer = per_cpu(irqGet, cpu); - - return len; -} - -static int gator_events_irq_start(void) -{ - // register tracepoints - if (hardirq_enabled) - if (GATOR_REGISTER_TRACE(irq_handler_exit)) - goto fail_hardirq_exit; - if (softirq_enabled) - if (GATOR_REGISTER_TRACE(softirq_exit)) - goto fail_softirq_exit; - pr_debug("gator: registered irq tracepoints\n"); - - return 0; - - // unregister tracepoints on error -fail_softirq_exit: - if (hardirq_enabled) - GATOR_UNREGISTER_TRACE(irq_handler_exit); -fail_hardirq_exit: - pr_err("gator: irq tracepoints failed to activate, please verify that tracepoints are enabled in the linux kernel\n"); - - return -1; -} - -static void gator_events_irq_stop(void) -{ - if (hardirq_enabled) - GATOR_UNREGISTER_TRACE(irq_handler_exit); - if (softirq_enabled) - GATOR_UNREGISTER_TRACE(softirq_exit); - pr_debug("gator: unregistered irq tracepoints\n"); - - hardirq_enabled = 0; - softirq_enabled = 0; -} - -static int gator_events_irq_read(int **buffer) -{ - unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt - int len, value; - int cpu = smp_processor_id(); - - len = 0; - if (hardirq_enabled) { - local_irq_save(flags); - value = per_cpu(irqCnt, cpu)[HARDIRQ]; - per_cpu(irqCnt, cpu)[HARDIRQ] = 0; - local_irq_restore(flags); - if (value != per_cpu(irqPrev, cpu)[HARDIRQ]) { - per_cpu(irqPrev, cpu)[HARDIRQ] = value; - per_cpu(irqGet, cpu)[len++] = hardirq_key; - per_cpu(irqGet, cpu)[len++] = value; - } - } - - if (softirq_enabled) { - local_irq_save(flags); - value = per_cpu(irqCnt, cpu)[SOFTIRQ]; - per_cpu(irqCnt, cpu)[SOFTIRQ] = 0; - local_irq_restore(flags); - if (value != per_cpu(irqPrev, cpu)[SOFTIRQ]) { - per_cpu(irqPrev, cpu)[SOFTIRQ] = value; - per_cpu(irqGet, cpu)[len++] = softirq_key; - per_cpu(irqGet, cpu)[len++] = value; - } - } - - if (buffer) - *buffer = per_cpu(irqGet, cpu); - - return len; -} - -static struct gator_interface gator_events_irq_interface = { - .create_files = gator_events_irq_create_files, - .online = gator_events_irq_online, - .start = gator_events_irq_start, - .stop = gator_events_irq_stop, - .read = gator_events_irq_read, -}; - -int gator_events_irq_init(void) -{ - hardirq_key = gator_events_get_key(); - softirq_key = gator_events_get_key(); - - hardirq_enabled = 0; - softirq_enabled = 0; - - return gator_events_install(&gator_events_irq_interface); -} -gator_events_init(gator_events_irq_init); diff --git a/drivers/gator/driver/gator_events_l2c-310.c b/drivers/gator/driver/gator_events_l2c-310.c deleted file mode 100644 index bd1c48a64e2..00000000000 --- a/drivers/gator/driver/gator_events_l2c-310.c +++ /dev/null @@ -1,179 +0,0 @@ -/** - * l2c310 (L2 Cache Controller) event counters for gator - * - * 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 -#include -#include - -#include "gator.h" - -#define L2C310_COUNTERS_NUM 2 - -static struct { - unsigned long enabled; - unsigned long event; - unsigned long key; -} l2c310_counters[L2C310_COUNTERS_NUM]; - -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); - - val |= ((1 << L2C310_COUNTERS_NUM) - 1) << 1; - - writel(val, l2c310_base + L2X0_EVENT_CNT_CTRL); -} - - -static int gator_events_l2c310_create_files(struct super_block *sb, - struct dentry *root) -{ - int i; - - for (i = 0; i < L2C310_COUNTERS_NUM; i++) { - char buf[16]; - struct dentry *dir; - - snprintf(buf, sizeof(buf), "L2C-310_cnt%d", i); - dir = gatorfs_mkdir(sb, root, buf); - if (WARN_ON(!dir)) - return -1; - gatorfs_create_ulong(sb, dir, "enabled", - &l2c310_counters[i].enabled); - gatorfs_create_ulong(sb, dir, "event", - &l2c310_counters[i].event); - gatorfs_create_ro_ulong(sb, dir, "key", - &l2c310_counters[i].key); - } - - return 0; -} - -static int gator_events_l2c310_start(void) -{ - static const unsigned long l2x0_event_cntx_cfg[L2C310_COUNTERS_NUM] = { - L2X0_EVENT_CNT0_CFG, - L2X0_EVENT_CNT1_CFG, - }; - int i; - - /* 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]); - - gator_events_l2c310_reset_counters(); - - /* Event counter enable */ - writel(1, l2c310_base + L2X0_EVENT_CNT_CTRL); - - return 0; -} - -static void gator_events_l2c310_stop(void) -{ - /* Event counter disable */ - writel(0, l2c310_base + L2X0_EVENT_CNT_CTRL); -} - -static int gator_events_l2c310_read(int **buffer) -{ - static const unsigned long l2x0_event_cntx_val[L2C310_COUNTERS_NUM] = { - L2X0_EVENT_CNT0_VAL, - L2X0_EVENT_CNT1_VAL, - }; - int i; - int len = 0; - - if (smp_processor_id()) - return 0; - - for (i = 0; i < L2C310_COUNTERS_NUM; i++) { - if (l2c310_counters[i].enabled) { - l2c310_buffer[len++] = l2c310_counters[i].key; - l2c310_buffer[len++] = readl(l2c310_base + - l2x0_event_cntx_val[i]); - } - } - - /* l2c310 counters are saturating, not wrapping in case of overflow */ - gator_events_l2c310_reset_counters(); - - if (buffer) - *buffer = l2c310_buffer; - - return len; -} - -static struct gator_interface gator_events_l2c310_interface = { - .create_files = gator_events_l2c310_create_files, - .start = gator_events_l2c310_start, - .stop = gator_events_l2c310_stop, - .read = gator_events_l2c310_read, -}; - -static void __maybe_unused gator_events_l2c310_probe(unsigned long phys) -{ - if (l2c310_base) - return; - - l2c310_base = ioremap(phys, SZ_4K); - if (l2c310_base) { - u32 cache_id = readl(l2c310_base + L2X0_CACHE_ID); - - if ((cache_id & 0xff0003c0) != 0x410000c0) { - iounmap(l2c310_base); - l2c310_base = NULL; - } - } -} - -int gator_events_l2c310_init(void) -{ - int i; - - if (gator_cpuid() != CORTEX_A5 && gator_cpuid() != CORTEX_A9) - return -1; - -#if defined(CONFIG_ARCH_EXYNOS4) || defined(CONFIG_ARCH_S5PV310) - gator_events_l2c310_probe(0x10502000); -#endif -#if defined(CONFIG_ARCH_OMAP4) - gator_events_l2c310_probe(0x48242000); -#endif -#if defined(CONFIG_ARCH_TEGRA) - gator_events_l2c310_probe(0x50043000); -#endif -#if defined(CONFIG_ARCH_U8500) - gator_events_l2c310_probe(0xa0412000); -#endif -#if defined(CONFIG_ARCH_VEXPRESS) - // A9x4 core tile (HBI-0191) - gator_events_l2c310_probe(0x1e00a000); - // New memory map tiles - gator_events_l2c310_probe(0x2c0f0000); -#endif - if (!l2c310_base) - return -1; - - for (i = 0; i < L2C310_COUNTERS_NUM; i++) { - l2c310_counters[i].enabled = 0; - l2c310_counters[i].key = gator_events_get_key(); - } - - return gator_events_install(&gator_events_l2c310_interface); -} -gator_events_init(gator_events_l2c310_init); diff --git a/drivers/gator/driver/gator_events_mali.c b/drivers/gator/driver/gator_events_mali.c deleted file mode 100644 index 31e8f0d9030..00000000000 --- a/drivers/gator/driver/gator_events_mali.c +++ /dev/null @@ -1,611 +0,0 @@ -/** - * 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 "gator.h" - -#include -#include -#include - -#include "linux/mali_linux_trace.h" - -#define ACTIVITY_START 1 -#define ACTIVITY_STOP 2 - -#ifndef MALI_SUPPORT -#error MALI_SUPPORT not defined! -#endif - -#define MALI_200 0x0a07 -#define MALI_300 0x0b06 //This is not actually true; Mali-300 is also 0x0b07 -#define MALI_400 0x0b07 -#define MALI_T6xx 0x0056 - -static const char *mali_name; - -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, - - NUMBER_OF_EVENTS -}; - -#define FIRST_ACTIVITY_EVENT ACTIVITY_VP -#define LAST_ACTIVITY_EVENT ACTIVITY_FP3 - -#define FIRST_HW_COUNTER COUNTER_L2_C0 -#define LAST_HW_COUNTER COUNTER_FP3_C1 - -#define FIRST_SW_COUNTER COUNTER_EGL_BLIT_TIME -#define LAST_SW_COUNTER COUNTER_GLES_LOOP_LINES_COUNT - -#define FIRST_SPECIAL_COUNTER COUNTER_FILMSTRIP -#define LAST_SPECIAL_COUNTER COUNTER_FILMSTRIP - -/* gatorfs variables for counter enable state, - * the event the counter should count and the - * 'key' (a unique id set by gatord and returned - * by gator.ko) - */ -static unsigned long counter_enabled[NUMBER_OF_EVENTS]; -static unsigned long counter_event[NUMBER_OF_EVENTS]; -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]; - -/* An array used to return the data we recorded - * as key,value pairs hence the *2 - */ -static unsigned long counter_dump[NUMBER_OF_EVENTS * 2]; -static unsigned long counter_prev[NUMBER_OF_EVENTS]; - -/* Note whether tracepoints have been registered */ -static int trace_registered; - -/** - * Calculate the difference and handle the overflow. - */ -static u32 get_difference(u32 start, u32 end) -{ - if (start - end >= 0) - { - return start - end; - } - - // Mali counters are unsigned 32 bit values that wrap. - return (4294967295u - end) + start; -} - -/** - * Returns non-zero if the given counter ID is an activity counter. - */ -static inline int is_activity_counter(unsigned int event_id) -{ - return (event_id >= FIRST_ACTIVITY_EVENT && - event_id <= LAST_ACTIVITY_EVENT); -} - -/** - * Returns non-zero if the given counter ID is a hardware counter. - */ -static inline int is_hw_counter(unsigned int event_id) -{ - return (event_id >= FIRST_HW_COUNTER && event_id <= LAST_HW_COUNTER); -} - -/** - * Returns non-zero if the given counter ID is a software counter. - */ -static inline int is_sw_counter(unsigned int event_id) -{ - return (event_id >= FIRST_SW_COUNTER && event_id <= LAST_SW_COUNTER); -} - -/* - * 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. - */ -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; -} - -/* 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)) -{ - /* 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; - } -} - -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); - } -} - -//TODO need to work out how many fp units we have -u32 gator_mali_get_n_fp(void) { - return 4; -} - -//TODO need to work out what kind of Mali we are looking at -u32 gator_mali_get_id(void) { - return MALI_SUPPORT; -} - -int gator_events_mali_create_files(struct super_block *sb, struct dentry *root) { - struct dentry *dir; - int event; - int n_fp = gator_mali_get_n_fp(); - - /* - * 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]; - - snprintf(buf, sizeof(buf), "ARM_%s_Filmstrip", mali_name); - - 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; -} - -//TODO -void _mali_profiling_set_event(unsigned int, unsigned int); -void _mali_osk_fb_control_set(unsigned int, unsigned int); - -void _mali_profiling_get_counters(unsigned int*, unsigned int*, unsigned int*, unsigned int*); -void (*_mali_profiling_get_counters_function_pointer)(unsigned int*, unsigned int*, unsigned int*, unsigned int*); - -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 - */ - void (*set_hw_event)(unsigned int, unsigned int); - void (*set_fb_event)(unsigned int, unsigned int); - - set_hw_event = symbol_get(_mali_profiling_set_event); - - if (set_hw_event) { - int i; - - pr_debug("gator: mali online _mali_profiling_set_event symbol @ %p\n",set_hw_event); - - for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) { - if (counter_enabled[i]) { - set_hw_event(i, counter_event[i]); - } else { - set_hw_event(i, 0xFFFFFFFF); - } - } - - symbol_put(_mali_profiling_set_event); - } else { - printk("gator: mali online _mali_profiling_set_event symbol not found\n"); - } - - set_fb_event = symbol_get(_mali_osk_fb_control_set); - - if (set_fb_event) { - pr_debug("gator: mali online _mali_osk_fb_control_set symbol @ %p\n", set_fb_event); - - 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"); - } - - _mali_profiling_get_counters_function_pointer = symbol_get(_mali_profiling_get_counters); - if (_mali_profiling_get_counters_function_pointer){ - pr_debug("gator: mali online _mali_profiling_get_counters symbol @ %p\n", _mali_profiling_get_counters_function_pointer); - 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) -{ - void (*set_hw_event)(unsigned int, unsigned int); - void (*set_fb_event)(unsigned int, unsigned int); - - set_hw_event = symbol_get(_mali_profiling_set_event); - - if (set_hw_event) { - int i; - - pr_debug("gator: mali offline _mali_profiling_set_event symbol @ %p\n",set_hw_event); - for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) { - set_hw_event(i, 0xFFFFFFFF); - } - - symbol_put(_mali_profiling_set_event); - } else { - printk("gator: mali offline _mali_profiling_set_event symbol not found\n"); - } - - set_fb_event = symbol_get(_mali_osk_fb_control_set); - - if (set_fb_event) { - pr_debug("gator: mali offline _mali_osk_fb_control_set symbol @ %p\n", set_fb_event); - - set_fb_event(0,0); - - symbol_put(_mali_osk_fb_control_set); - } else { - printk("gator: mali offline _mali_osk_fb_control_set symbol not found\n"); - } - - if (_mali_profiling_get_counters_function_pointer){ - symbol_put(_mali_profiling_get_counters); - } - -} - -static int gator_events_mali_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_REGISTER_TRACE(mali_sw_counter)) { - printk("gator: mali_sw_counter tracepoint failed to activate\n"); - return -1; - } - - trace_registered = 1; - - mali_counter_initialize(); - return 0; -} - -static void gator_events_mali_stop(void) { - unsigned int cnt; - - pr_debug("gator: mali stop\n"); - - if (trace_registered) { - GATOR_UNREGISTER_TRACE(mali_hw_counter); - GATOR_UNREGISTER_TRACE(mali_sw_counter); - - 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; - } - - mali_counter_deinitialize(); -} - -static int gator_events_mali_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_profiling_get_counters_function_pointer){ - _mali_profiling_get_counters_function_pointer(&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]) { - u32 value = 0; - - // Determine the current value of the counter. - if( counter_address[cnt] != NULL && 0 ) { // Never true! - value = *counter_address[cnt]; - } else if (counter_data[cnt]!=0) { - value = counter_data[cnt]; - counter_data[cnt] = 0; - } - - // Send the counter value only if it differs from last time. - if (value != counter_prev[cnt]) { - counter_prev[cnt] = value; - counter_dump[len++] = counter_key[cnt]; - counter_dump[len++] = value; - } - } - } - - if (buffer) { - *buffer = (int*) counter_dump; - } - - return len; -} - -static struct gator_interface gator_events_mali_interface = { - .create_files = gator_events_mali_create_files, - .start = gator_events_mali_start, - .stop = gator_events_mali_stop, - .read = gator_events_mali_read, -}; - -int gator_events_mali_init(void) -{ - unsigned int cnt; - u32 id = gator_mali_get_id(); - - switch (id) { - case MALI_T6xx: - mali_name = "Mali-T6xx"; - break; - case MALI_400: - mali_name = "Mali-400"; - break; - case MALI_300: - mali_name = "Mali-300"; - break; - case MALI_200: - mali_name = "Mali-200"; - break; - default: - printk("Unknown Mali ID (%d)\n", id); - return -1; - } - - 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; - } - - trace_registered = 0; - - return gator_events_install(&gator_events_mali_interface); -} -gator_events_init(gator_events_mali_init); diff --git a/drivers/gator/driver/gator_events_meminfo.c b/drivers/gator/driver/gator_events_meminfo.c deleted file mode 100644 index c763634ef53..00000000000 --- a/drivers/gator/driver/gator_events_meminfo.c +++ /dev/null @@ -1,225 +0,0 @@ -/** - * 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 "gator.h" -#include -#include - -#define MEMINFO_MEMFREE 0 -#define MEMINFO_MEMUSED 1 -#define MEMINFO_BUFFERRAM 2 -#define MEMINFO_TOTAL 3 - -static ulong meminfo_global_enabled; -static ulong meminfo_enabled[MEMINFO_TOTAL]; -static ulong meminfo_key[MEMINFO_TOTAL]; -static unsigned long long meminfo_buffer[MEMINFO_TOTAL * 2]; -static int meminfo_length = 0; -static unsigned int mem_event = 0; -static bool new_data_avail; - -static void wq_sched_handler(struct work_struct *wsptr); - -DECLARE_WORK(work, wq_sched_handler); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0) -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)) { -#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)) { -#else -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)) { - mem_event++; -} - -static int gator_events_meminfo_create_files(struct super_block *sb, struct dentry *root) -{ - struct dentry *dir; - int i; - - for (i = 0; i < MEMINFO_TOTAL; i++) { - switch (i) { - case MEMINFO_MEMFREE: - dir = gatorfs_mkdir(sb, root, "Linux_meminfo_memfree"); - break; - case MEMINFO_MEMUSED: - dir = gatorfs_mkdir(sb, root, "Linux_meminfo_memused"); - break; - case MEMINFO_BUFFERRAM: - dir = gatorfs_mkdir(sb, root, "Linux_meminfo_bufferram"); - break; - default: - return -1; - } - if (!dir) { - return -1; - } - gatorfs_create_ulong(sb, dir, "enabled", &meminfo_enabled[i]); - gatorfs_create_ro_ulong(sb, dir, "key", &meminfo_key[i]); - } - - return 0; -} - -static int gator_events_meminfo_start(void) -{ - int i; - - new_data_avail = true; - for (i = 0; i < MEMINFO_TOTAL; i++) { - if (meminfo_enabled[i]) { - meminfo_global_enabled = 1; - } - } - - if (meminfo_global_enabled == 0) - return 0; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0) - if (GATOR_REGISTER_TRACE(mm_page_free_direct)) -#else - if (GATOR_REGISTER_TRACE(mm_page_free)) -#endif - goto mm_page_free_exit; -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0) - if (GATOR_REGISTER_TRACE(mm_pagevec_free)) -#else - if (GATOR_REGISTER_TRACE(mm_page_free_batched)) -#endif - goto mm_page_free_batched_exit; - if (GATOR_REGISTER_TRACE(mm_page_alloc)) - goto mm_page_alloc_exit; - - return 0; - -mm_page_alloc_exit: -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0) - GATOR_UNREGISTER_TRACE(mm_pagevec_free); -#else - GATOR_UNREGISTER_TRACE(mm_page_free_batched); -#endif -mm_page_free_batched_exit: -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0) - GATOR_UNREGISTER_TRACE(mm_page_free_direct); -#else - GATOR_UNREGISTER_TRACE(mm_page_free); -#endif -mm_page_free_exit: - return -1; -} - -static void gator_events_meminfo_stop(void) -{ - int i; - - if (meminfo_global_enabled) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0) - GATOR_UNREGISTER_TRACE(mm_page_free_direct); - GATOR_UNREGISTER_TRACE(mm_pagevec_free); -#else - GATOR_UNREGISTER_TRACE(mm_page_free); - GATOR_UNREGISTER_TRACE(mm_page_free_batched); -#endif - GATOR_UNREGISTER_TRACE(mm_page_alloc); - } - - meminfo_global_enabled = 0; - for (i = 0; i < MEMINFO_TOTAL; i++) { - meminfo_enabled[i] = 0; - } -} - -// Must be run in a work queue as the kernel function si_meminfo() can sleep -static void wq_sched_handler(struct work_struct *wsptr) -{ - struct sysinfo info; - int i, len; - unsigned long long value; - - meminfo_length = len = 0; - - si_meminfo(&info); - for (i = 0; i < MEMINFO_TOTAL; i++) { - if (meminfo_enabled[i]) { - switch (i) { - case MEMINFO_MEMFREE: - value = info.freeram * PAGE_SIZE; - break; - case MEMINFO_MEMUSED: - value = (info.totalram - info.freeram) * PAGE_SIZE; - break; - case MEMINFO_BUFFERRAM: - value = info.bufferram * PAGE_SIZE; - break; - default: - value = 0; - break; - } - meminfo_buffer[len++] = (unsigned long long)meminfo_key[i]; - meminfo_buffer[len++] = value; - } - } - - meminfo_length = len; - new_data_avail = true; -} - -static int gator_events_meminfo_read(long long **buffer) -{ - static unsigned int last_mem_event = 0; - - if (smp_processor_id() || !meminfo_global_enabled) - return 0; - - if (last_mem_event != mem_event) { - last_mem_event = mem_event; - schedule_work(&work); - } - - if (!new_data_avail) - return 0; - - new_data_avail = false; - - if (buffer) - *buffer = meminfo_buffer; - - return meminfo_length; -} - -static struct gator_interface gator_events_meminfo_interface = { - .create_files = gator_events_meminfo_create_files, - .start = gator_events_meminfo_start, - .stop = gator_events_meminfo_stop, - .read64 = gator_events_meminfo_read, -}; - -int gator_events_meminfo_init(void) -{ - int i; - - meminfo_global_enabled = 0; - for (i = 0; i < MEMINFO_TOTAL; i++) { - meminfo_enabled[i] = 0; - meminfo_key[i] = gator_events_get_key(); - } - - return gator_events_install(&gator_events_meminfo_interface); -} -gator_events_init(gator_events_meminfo_init); diff --git a/drivers/gator/driver/gator_events_mmaped.c b/drivers/gator/driver/gator_events_mmaped.c deleted file mode 100644 index acd5f85ebb7..00000000000 --- a/drivers/gator/driver/gator_events_mmaped.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Example events provider - * - * 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. - * - * Similar entries to those below must be present in the events.xml file. - * To add them to the events.xml, create an events-mmap.xml with the - * following contents and rebuild gatord: - * - * - * - * - * - * - * - * - * - * - */ - -#include -#include -#include - -#include "gator.h" - -#define MMAPED_COUNTERS_NUM 3 - -static struct { - unsigned long enabled; - unsigned long event; - unsigned long key; -} mmaped_counters[MMAPED_COUNTERS_NUM]; - -static int mmaped_buffer[MMAPED_COUNTERS_NUM * 2]; - -#ifdef TODO -static void __iomem *mmaped_base; -#endif - -/* Adds mmaped_cntX directories and enabled, event, and key files to /dev/gator/driver/events */ -static int gator_events_mmaped_create_files(struct super_block *sb, - struct dentry *root) -{ - int i; - - for (i = 0; i < MMAPED_COUNTERS_NUM; i++) { - char buf[16]; - struct dentry *dir; - - snprintf(buf, sizeof(buf), "mmaped_cnt%d", i); - dir = gatorfs_mkdir(sb, root, buf); - if (WARN_ON(!dir)) - return -1; - gatorfs_create_ulong(sb, dir, "enabled", - &mmaped_counters[i].enabled); - gatorfs_create_ulong(sb, dir, "event", - &mmaped_counters[i].event); - gatorfs_create_ro_ulong(sb, dir, "key", - &mmaped_counters[i].key); - } - - return 0; -} - -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]); - - writel(ENABLED, COUNTERS_CONTROL_OFFSET); -#endif - - return 0; -} - -static void gator_events_mmaped_stop(void) -{ -#ifdef TODO - writel(DISABLED, COUNTERS_CONTROL_OFFSET); -#endif -} - -#ifndef TODO -/* This function "simulates" counters, generating values of fancy - * functions like sine or triangle... */ -static int mmaped_simulate(int counter) -{ - int result = 0; - - switch (counter) { - case 0: /* sort-of-sine */ - { - static int t; - int x; - - if (t % 1024 < 512) - x = 512 - (t % 512); - else - x = t % 512; - - result = 32 * x / 512; - result = result * result; - - if (t < 1024) - result = 1922 - result; - - t = (t + 1) % 2048; - } - break; - case 1: /* triangle */ - { - static int v, d = 1; - - v += d; - if (v % 2000 == 0) - d = -d; - - result = v; - } - break; - case 2: /* PWM signal */ - { - static int t, dc; - - t = (t + 1) % 2000; - if (t % 100) - dc = (dc + 200) % 2000; - - result = t < dc ? 0 : 2000; - } - break; - } - - return result; -} -#endif - -static int gator_events_mmaped_read(int **buffer) -{ - int i; - int len = 0; - - /* System wide counters - read from one core only */ - if (smp_processor_id()) - return 0; - - for (i = 0; i < MMAPED_COUNTERS_NUM; i++) { - if (mmaped_counters[i].enabled) { - mmaped_buffer[len++] = mmaped_counters[i].key; -#ifdef TODO - mmaped_buffer[len++] = readl(mmaped_base + - COUNTERS_VALUE_OFFSET[i]); -#else - mmaped_buffer[len++] = mmaped_simulate( - mmaped_counters[i].event); -#endif - } - } - - if (buffer) - *buffer = mmaped_buffer; - - return len; -} - -static struct gator_interface gator_events_mmaped_interface = { - .create_files = gator_events_mmaped_create_files, - .start = gator_events_mmaped_start, - .stop = gator_events_mmaped_stop, - .read = gator_events_mmaped_read, -}; - -/* Must not be static! */ -int __init gator_events_mmaped_init(void) -{ - int i; - -#ifdef TODO - mmaped_base = ioremap(COUNTERS_PHYS_ADDR, SZ_4K); - if (!mmaped_base) - return -ENOMEM; -#endif - - for (i = 0; i < MMAPED_COUNTERS_NUM; i++) { - mmaped_counters[i].enabled = 0; - mmaped_counters[i].key = gator_events_get_key(); - } - - return gator_events_install(&gator_events_mmaped_interface); -} -gator_events_init(gator_events_mmaped_init); diff --git a/drivers/gator/driver/gator_events_net.c b/drivers/gator/driver/gator_events_net.c deleted file mode 100644 index ef1623b9a25..00000000000 --- a/drivers/gator/driver/gator_events_net.c +++ /dev/null @@ -1,144 +0,0 @@ -/** - * 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 "gator.h" -#include - -#define NETRX 0 -#define NETTX 1 -#define TOTALNET 2 - -static ulong netrx_enabled; -static ulong nettx_enabled; -static ulong netrx_key; -static ulong nettx_key; -static int rx_total, tx_total; -static ulong netPrev[TOTALNET]; -static int netGet[TOTALNET * 2]; - -static void get_network_stats(struct work_struct *wsptr) { - int rx = 0, tx = 0; - struct net_device *dev; - - for_each_netdev(&init_net, dev) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) - const struct net_device_stats *stats = dev_get_stats(dev); -#else - struct rtnl_link_stats64 temp; - const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp); -#endif - rx += stats->rx_bytes; - tx += stats->tx_bytes; - } - rx_total = rx; - tx_total = tx; -} -DECLARE_WORK(wq_get_stats, get_network_stats); - -static void calculate_delta(int *rx, int *tx) -{ - int rx_calc, tx_calc; - - rx_calc = (int)(rx_total - netPrev[NETRX]); - if (rx_calc < 0) - rx_calc = 0; - netPrev[NETRX] += rx_calc; - - tx_calc = (int)(tx_total - netPrev[NETTX]); - if (tx_calc < 0) - tx_calc = 0; - netPrev[NETTX] += tx_calc; - - *rx = rx_calc; - *tx = tx_calc; -} - -static int gator_events_net_create_files(struct super_block *sb, struct dentry *root) -{ - struct dentry *dir; - - dir = gatorfs_mkdir(sb, root, "Linux_net_rx"); - if (!dir) { - return -1; - } - gatorfs_create_ulong(sb, dir, "enabled", &netrx_enabled); - gatorfs_create_ro_ulong(sb, dir, "key", &netrx_key); - - dir = gatorfs_mkdir(sb, root, "Linux_net_tx"); - if (!dir) { - return -1; - } - gatorfs_create_ulong(sb, dir, "enabled", &nettx_enabled); - gatorfs_create_ro_ulong(sb, dir, "key", &nettx_key); - - return 0; -} - -static int gator_events_net_start(void) -{ - get_network_stats(NULL); - netPrev[NETRX] = rx_total; - netPrev[NETTX] = tx_total; - return 0; -} - -static void gator_events_net_stop(void) -{ - netrx_enabled = 0; - nettx_enabled = 0; -} - -static int gator_events_net_read(int **buffer) -{ - int len, rx_delta, tx_delta; - static int last_rx_delta = 0, last_tx_delta = 0; - - if (smp_processor_id() != 0) - return 0; - - schedule_work(&wq_get_stats); - calculate_delta(&rx_delta, &tx_delta); - - len = 0; - if (netrx_enabled && last_rx_delta != rx_delta) { - last_rx_delta = rx_delta; - netGet[len++] = netrx_key; - netGet[len++] = rx_delta; - } - - if (nettx_enabled && last_tx_delta != tx_delta) { - last_tx_delta = tx_delta; - netGet[len++] = nettx_key; - netGet[len++] = tx_delta; - } - - if (buffer) - *buffer = netGet; - - return len; -} - -static struct gator_interface gator_events_net_interface = { - .create_files = gator_events_net_create_files, - .start = gator_events_net_start, - .stop = gator_events_net_stop, - .read = gator_events_net_read, -}; - -int gator_events_net_init(void) -{ - netrx_key = gator_events_get_key(); - nettx_key = gator_events_get_key(); - - netrx_enabled = 0; - nettx_enabled = 0; - - return gator_events_install(&gator_events_net_interface); -} -gator_events_init(gator_events_net_init); diff --git a/drivers/gator/driver/gator_events_perf_pmu.c b/drivers/gator/driver/gator_events_perf_pmu.c deleted file mode 100644 index 322ebc430ec..00000000000 --- a/drivers/gator/driver/gator_events_perf_pmu.c +++ /dev/null @@ -1,296 +0,0 @@ -/** - * 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 -#include -#include "gator.h" - -// gator_events_armvX.c is used for Linux 2.6.x -#if GATOR_PERF_PMU_SUPPORT - -static const char *pmnc_name; -int pmnc_counters; -int ccnt = 0; - -#define CNTMAX (6+1) - -unsigned long pmnc_enabled[CNTMAX]; -unsigned long pmnc_event[CNTMAX]; -unsigned long pmnc_count[CNTMAX]; -unsigned long pmnc_key[CNTMAX]; - -static DEFINE_PER_CPU(int[CNTMAX], perfCurr); -static DEFINE_PER_CPU(int[CNTMAX], perfPrev); -static DEFINE_PER_CPU(int[CNTMAX], perfPrevDelta); -static DEFINE_PER_CPU(int[CNTMAX * 2], perfCnt); -static DEFINE_PER_CPU(struct perf_event *[CNTMAX], pevent); -static DEFINE_PER_CPU(struct perf_event_attr *[CNTMAX], pevent_attr); - -static void gator_events_perf_pmu_stop(void); - -static int gator_events_perf_pmu_create_files(struct super_block *sb, struct dentry *root) -{ - struct dentry *dir; - int i; - - for (i = 0; i < pmnc_counters; i++) { - char buf[40]; - if (i == 0) { - snprintf(buf, sizeof buf, "%s_ccnt", pmnc_name); - } else { - 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_ulong(sb, dir, "count", &pmnc_count[i]); - gatorfs_create_ro_ulong(sb, dir, "key", &pmnc_key[i]); - if (i > 0) { - gatorfs_create_ulong(sb, dir, "event", &pmnc_event[i]); - } - } - - return 0; -} - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) -static void dummy_handler(struct perf_event *event, int unused, struct perf_sample_data *data, struct pt_regs *regs) -#else -static void dummy_handler(struct perf_event *event, struct perf_sample_data *data, struct pt_regs *regs) -#endif -{ -// 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) -{ - 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]; - 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); - per_cpu(perfPrevDelta, cpu)[cnt] = 0; - per_cpu(perfCnt, cpu)[len++] = pmnc_key[cnt]; - per_cpu(perfCnt, cpu)[len++] = 0; - } - } - - if (buffer) - *buffer = per_cpu(perfCnt, cpu); - - return len; -} - -static void gator_events_perf_pmu_online_dispatch(int cpu) -{ - int cnt; - - for (cnt = 0; cnt < pmnc_counters; cnt++) { - if (per_cpu(pevent, cpu)[cnt] != NULL || per_cpu(pevent_attr, cpu)[cnt] == 0) - continue; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) - per_cpu(pevent, cpu)[cnt] = perf_event_create_kernel_counter(per_cpu(pevent_attr, cpu)[cnt], cpu, 0, dummy_handler); -#else - per_cpu(pevent, cpu)[cnt] = perf_event_create_kernel_counter(per_cpu(pevent_attr, cpu)[cnt], cpu, 0, dummy_handler, 0); -#endif - if (IS_ERR(per_cpu(pevent, cpu)[cnt])) { - pr_debug("gator: unable to online a counter on cpu %d\n", cpu); - per_cpu(pevent, cpu)[cnt] = NULL; - continue; - } - - if (per_cpu(pevent, cpu)[cnt]->state != PERF_EVENT_STATE_ACTIVE) { - pr_debug("gator: inactive counter on cpu %d\n", cpu); - perf_event_release_kernel(per_cpu(pevent, cpu)[cnt]); - per_cpu(pevent, cpu)[cnt] = NULL; - continue; - } - } -} - -static void gator_events_perf_pmu_offline_dispatch(int cpu) -{ - int cnt; - - for (cnt = 0; cnt < pmnc_counters; cnt++) { - if (per_cpu(pevent, cpu)[cnt] != NULL) { - perf_event_release_kernel(per_cpu(pevent, cpu)[cnt]); - per_cpu(pevent, cpu)[cnt] = NULL; - } - } -} - -static int gator_events_perf_pmu_start(void) -{ - int cnt, cpu; - u32 size = sizeof(struct perf_event_attr); - - for_each_present_cpu(cpu) { - for (cnt = 0; cnt < pmnc_counters; cnt++) { - per_cpu(pevent, cpu)[cnt] = NULL; - if (!pmnc_enabled[cnt] || pmnc_count[cnt] > 0) // Skip disabled counters and EBS counters - continue; - - per_cpu(perfPrev, cpu)[cnt] = 0; - per_cpu(perfCurr, cpu)[cnt] = 0; - per_cpu(perfPrevDelta, cpu)[cnt] = 0; - per_cpu(pevent_attr, cpu)[cnt] = kmalloc(size, GFP_KERNEL); - if (!per_cpu(pevent_attr, cpu)[cnt]) { - gator_events_perf_pmu_stop(); - return -1; - } - - memset(per_cpu(pevent_attr, cpu)[cnt], 0, size); - per_cpu(pevent_attr, cpu)[cnt]->type = PERF_TYPE_RAW; - per_cpu(pevent_attr, cpu)[cnt]->size = size; - per_cpu(pevent_attr, cpu)[cnt]->config = pmnc_event[cnt]; - per_cpu(pevent_attr, cpu)[cnt]->sample_period = 0; - per_cpu(pevent_attr, cpu)[cnt]->pinned = 1; - - // handle special case for ccnt - if (cnt == ccnt) { - per_cpu(pevent_attr, cpu)[cnt]->type = PERF_TYPE_HARDWARE; - per_cpu(pevent_attr, cpu)[cnt]->config = PERF_COUNT_HW_CPU_CYCLES; - } - } - } - - return 0; -} - -static void gator_events_perf_pmu_stop(void) -{ - unsigned int cnt, cpu; - - for_each_present_cpu(cpu) { - for (cnt = 0; cnt < pmnc_counters; cnt++) { - if (per_cpu(pevent_attr, cpu)[cnt]) { - kfree(per_cpu(pevent_attr, cpu)[cnt]); - per_cpu(pevent_attr, cpu)[cnt] = NULL; - } - } - } - - for (cnt = 0; cnt < pmnc_counters; cnt++) { - pmnc_enabled[cnt] = 0; - pmnc_event[cnt] = 0; - pmnc_count[cnt] = 0; - } -} - -static int gator_events_perf_pmu_read(int **buffer) -{ - int cnt, delta, len = 0; - int cpu = smp_processor_id(); - - for (cnt = 0; cnt < pmnc_counters; 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); - delta = per_cpu(perfCurr, cpu)[cnt] - per_cpu(perfPrev, cpu)[cnt]; - if (delta != per_cpu(perfPrevDelta, cpu)[cnt]) { - per_cpu(perfPrevDelta, cpu)[cnt] = delta; - per_cpu(perfPrev, cpu)[cnt] = per_cpu(perfCurr, cpu)[cnt]; - per_cpu(perfCnt, cpu)[len++] = pmnc_key[cnt]; - if (delta < 0) - delta *= -1; - per_cpu(perfCnt, cpu)[len++] = delta; - } - } - } - - if (buffer) - *buffer = per_cpu(perfCnt, cpu); - - return len; -} - -static struct gator_interface gator_events_perf_pmu_interface = { - .create_files = gator_events_perf_pmu_create_files, - .start = gator_events_perf_pmu_start, - .stop = gator_events_perf_pmu_stop, - .online = gator_events_perf_pmu_online, - .online_dispatch = gator_events_perf_pmu_online_dispatch, - .offline_dispatch = gator_events_perf_pmu_offline_dispatch, - .read = gator_events_perf_pmu_read, -}; - -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; - default: - return -1; - } - - pmnc_counters++; // CNT[n] + CCNT - - for (cnt = 0; cnt < CNTMAX; cnt++) { - pmnc_enabled[cnt] = 0; - pmnc_event[cnt] = 0; - pmnc_count[cnt] = 0; - pmnc_key[cnt] = gator_events_get_key(); - } - - return gator_events_install(&gator_events_perf_pmu_interface); -} - -gator_events_init(gator_events_perf_pmu_init); -#endif diff --git a/drivers/gator/driver/gator_events_power.c b/drivers/gator/driver/gator_events_power.c deleted file mode 100644 index a0ae684827d..00000000000 --- a/drivers/gator/driver/gator_events_power.c +++ /dev/null @@ -1,178 +0,0 @@ -/** - * Copyright (C) ARM Limited 2011-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 "gator.h" -#include -#include -#include - -// 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 -// CPU Idle is currently disabled in the .xml -#if GATOR_CPU_FREQ_SUPPORT -enum { - POWER_CPU_FREQ, - POWER_CPU_IDLE, - POWER_TOTAL -}; - -static ulong power_cpu_enabled[POWER_TOTAL]; -static ulong power_cpu_key[POWER_TOTAL]; -static DEFINE_PER_CPU(ulong[POWER_TOTAL], power); -static DEFINE_PER_CPU(ulong[POWER_TOTAL], prev); -static DEFINE_PER_CPU(int *, powerGet); - -GATOR_DEFINE_PROBE(cpu_frequency, TP_PROTO(unsigned int frequency, unsigned int cpu)) -{ - per_cpu(power, cpu)[POWER_CPU_FREQ] = frequency * 1000; -} - -GATOR_DEFINE_PROBE(cpu_idle, TP_PROTO(unsigned int state, unsigned int cpu)) -{ - per_cpu(power, cpu)[POWER_CPU_IDLE] = state; -} - -static int gator_events_power_create_files(struct super_block *sb, struct dentry *root) -{ - struct dentry *dir; - - // cpu_frequency - dir = gatorfs_mkdir(sb, root, "Linux_power_cpu_freq"); - if (!dir) { - return -1; - } - gatorfs_create_ulong(sb, dir, "enabled", &power_cpu_enabled[POWER_CPU_FREQ]); - gatorfs_create_ro_ulong(sb, dir, "key", &power_cpu_key[POWER_CPU_FREQ]); - - // cpu_idle - dir = gatorfs_mkdir(sb, root, "Linux_power_cpu_idle"); - if (!dir) { - return -1; - } - gatorfs_create_ulong(sb, dir, "enabled", &power_cpu_enabled[POWER_CPU_IDLE]); - gatorfs_create_ro_ulong(sb, dir, "key", &power_cpu_key[POWER_CPU_IDLE]); - - return 0; -} - -static int gator_events_power_populate(int cpu, int** buffer) -{ - int i, len = 0; - - for (i = 0; i < POWER_TOTAL; i++) { - if (power_cpu_enabled[i]) { - if (per_cpu(power, cpu)[i] != per_cpu(prev, cpu)[i]) { - per_cpu(prev, cpu)[i] = per_cpu(power, cpu)[i]; - per_cpu(powerGet, cpu)[len++] = power_cpu_key[i]; - per_cpu(powerGet, cpu)[len++] = per_cpu(power, cpu)[i]; - } - } - } - - if (buffer) - *buffer = per_cpu(powerGet, cpu); - - return len; -} - -static int gator_events_power_online(int** buffer) -{ - int i, cpu = smp_processor_id(); - for (i = 0; i < POWER_TOTAL; i++) - per_cpu(prev, cpu)[i] = -1; - per_cpu(power, cpu)[POWER_CPU_FREQ] = cpufreq_quick_get(cpu) * 1000; - return gator_events_power_populate(cpu, buffer); -} - -static int gator_events_power_offline(int** buffer) -{ - int cpu = smp_processor_id(); - // Set frequency to zero on an offline - per_cpu(power, cpu)[POWER_CPU_FREQ] = 0; - return gator_events_power_populate(cpu, buffer); -} - -static int gator_events_power_start(void) -{ - int cpu; - - for_each_present_cpu(cpu) { - per_cpu(powerGet, cpu) = kmalloc(POWER_TOTAL * 2, GFP_KERNEL); - if (!per_cpu(powerGet, cpu)) - return -1; - } - - // register tracepoints - if (power_cpu_enabled[POWER_CPU_FREQ]) - if (GATOR_REGISTER_TRACE(cpu_frequency)) - goto fail_cpu_frequency_exit; - if (power_cpu_enabled[POWER_CPU_IDLE]) - if (GATOR_REGISTER_TRACE(cpu_idle)) - goto fail_cpu_idle_exit; - pr_debug("gator: registered power event tracepoints\n"); - - return 0; - - // unregister tracepoints on error -fail_cpu_idle_exit: - GATOR_UNREGISTER_TRACE(cpu_frequency); -fail_cpu_frequency_exit: - pr_err("gator: power event tracepoints failed to activate, please verify that tracepoints are enabled in the linux kernel\n"); - - return -1; -} - -static void gator_events_power_stop(void) -{ - int i, cpu; - if (power_cpu_enabled[POWER_CPU_FREQ]) - GATOR_UNREGISTER_TRACE(cpu_frequency); - if (power_cpu_enabled[POWER_CPU_IDLE]) - GATOR_UNREGISTER_TRACE(cpu_idle); - pr_debug("gator: unregistered power event tracepoints\n"); - - for (i = 0; i < POWER_TOTAL; i++) { - power_cpu_enabled[i] = 0; - } - - for_each_present_cpu(cpu) { - kfree(per_cpu(powerGet, cpu)); - } -} - -static int gator_events_power_read(int **buffer) -{ - return gator_events_power_populate(smp_processor_id(), buffer); -} - -static struct gator_interface gator_events_power_interface = { - .create_files = gator_events_power_create_files, - .online = gator_events_power_online, - .offline = gator_events_power_offline, - .start = gator_events_power_start, - .stop = gator_events_power_stop, - .read = gator_events_power_read, -}; -#endif - -int gator_events_power_init(void) -{ -#if (GATOR_CPU_FREQ_SUPPORT) - int i; - for (i = 0; i < POWER_TOTAL; i++) { - power_cpu_enabled[i] = 0; - power_cpu_key[i] = gator_events_get_key(); - } - - return gator_events_install(&gator_events_power_interface); -#else - return -1; -#endif -} -gator_events_init(gator_events_power_init); diff --git a/drivers/gator/driver/gator_events_sched.c b/drivers/gator/driver/gator_events_sched.c deleted file mode 100644 index 9bed3641dbb..00000000000 --- a/drivers/gator/driver/gator_events_sched.c +++ /dev/null @@ -1,114 +0,0 @@ -/** - * 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 "gator.h" -#include - -#define SCHED_SWITCH 0 -#define SCHED_TOTAL (SCHED_SWITCH+1) - -static ulong sched_switch_enabled; -static ulong sched_switch_key; -static DEFINE_PER_CPU(int[SCHED_TOTAL], schedCnt); -static DEFINE_PER_CPU(int[SCHED_TOTAL * 2], schedGet); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) -GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct rq *rq, struct task_struct *prev, struct task_struct *next)) -#else -GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct task_struct *prev, struct task_struct *next)) -#endif -{ - unsigned long flags; - - // disable interrupts to synchronize with gator_events_sched_read() - // spinlocks not needed since percpu buffers are used - local_irq_save(flags); - per_cpu(schedCnt, smp_processor_id())[SCHED_SWITCH]++; - local_irq_restore(flags); -} - -static int gator_events_sched_create_files(struct super_block *sb, struct dentry *root) -{ - struct dentry *dir; - - /* switch */ - dir = gatorfs_mkdir(sb, root, "Linux_sched_switch"); - if (!dir) { - return -1; - } - gatorfs_create_ulong(sb, dir, "enabled", &sched_switch_enabled); - gatorfs_create_ro_ulong(sb, dir, "key", &sched_switch_key); - - return 0; -} - -static int gator_events_sched_start(void) -{ - // register tracepoints - if (sched_switch_enabled) - if (GATOR_REGISTER_TRACE(sched_switch)) - goto sched_switch_exit; - pr_debug("gator: registered scheduler event tracepoints\n"); - - return 0; - - // unregister tracepoints on error -sched_switch_exit: - pr_err("gator: scheduler event tracepoints failed to activate, please verify that tracepoints are enabled in the linux kernel\n"); - - return -1; -} - -static void gator_events_sched_stop(void) -{ - if (sched_switch_enabled) - GATOR_UNREGISTER_TRACE(sched_switch); - pr_debug("gator: unregistered scheduler event tracepoints\n"); - - sched_switch_enabled = 0; -} - -static int gator_events_sched_read(int **buffer) -{ - unsigned long flags; - int len, value; - int cpu = smp_processor_id(); - - len = 0; - if (sched_switch_enabled) { - local_irq_save(flags); - value = per_cpu(schedCnt, cpu)[SCHED_SWITCH]; - per_cpu(schedCnt, cpu)[SCHED_SWITCH] = 0; - local_irq_restore(flags); - per_cpu(schedGet, cpu)[len++] = sched_switch_key; - per_cpu(schedGet, cpu)[len++] = value; - } - - if (buffer) - *buffer = per_cpu(schedGet, cpu); - - return len; -} - -static struct gator_interface gator_events_sched_interface = { - .create_files = gator_events_sched_create_files, - .start = gator_events_sched_start, - .stop = gator_events_sched_stop, - .read = gator_events_sched_read, -}; - -int gator_events_sched_init(void) -{ - sched_switch_enabled = 0; - - sched_switch_key = gator_events_get_key(); - - return gator_events_install(&gator_events_sched_interface); -} -gator_events_init(gator_events_sched_init); diff --git a/drivers/gator/driver/gator_events_scorpion.c b/drivers/gator/driver/gator_events_scorpion.c deleted file mode 100644 index 477e7c98948..00000000000 --- a/drivers/gator/driver/gator_events_scorpion.c +++ /dev/null @@ -1,678 +0,0 @@ -/** - * Copyright (C) ARM Limited 2011-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 "gator.h" - -// gator_events_perf_pmu.c is used if perf is supported -#if GATOR_NO_PERF_SUPPORT - -static const char *pmnc_name; -static int pmnc_counters; - -// Per-CPU PMNC: config reg -#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_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 */ - -// ccnt reg -#define CCNT_REG (1 << 31) - -#define CCNT 0 -#define CNT0 1 -#define CNTMAX (4+1) - -static unsigned long pmnc_enabled[CNTMAX]; -static unsigned long pmnc_event[CNTMAX]; -static unsigned long pmnc_key[CNTMAX]; - -static DEFINE_PER_CPU(int[CNTMAX], perfPrev); -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, -#ifdef CONFIG_ARCH_MSM_SCORPIONMP - 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, -#endif - MSM_MAX_EVT -}; - -struct scorp_evt { - u32 evt_type; - u32 val; - u8 grp; - u32 evt_type_act; -}; - -static const struct scorp_evt sc_evt[] = { - {SCORPION_ICACHE_EXPL_INV, 0x80000500, 0, 0x4d}, - {SCORPION_ICACHE_MISS, 0x80050000, 0, 0x4e}, - {SCORPION_ICACHE_ACCESS, 0x85000000, 0, 0x4f}, - {SCORPION_ICACHE_CACHEREQ_L2, 0x86000000, 0, 0x4f}, - {SCORPION_ICACHE_NOCACHE_L2, 0x87000000, 0, 0x4f}, - {SCORPION_HIQUP_NOPED, 0x80080000, 0, 0x4e}, - {SCORPION_DATA_ABORT, 0x8000000a, 0, 0x4c}, - {SCORPION_IRQ, 0x80000a00, 0, 0x4d}, - {SCORPION_FIQ, 0x800a0000, 0, 0x4e}, - {SCORPION_ALL_EXCPT, 0x8a000000, 0, 0x4f}, - {SCORPION_UNDEF, 0x8000000b, 0, 0x4c}, - {SCORPION_SVC, 0x80000b00, 0, 0x4d}, - {SCORPION_SMC, 0x800b0000, 0, 0x4e}, - {SCORPION_PREFETCH_ABORT, 0x8b000000, 0, 0x4f}, - {SCORPION_INDEX_CHECK, 0x8000000c, 0, 0x4c}, - {SCORPION_NULL_CHECK, 0x80000c00, 0, 0x4d}, - {SCORPION_EXPL_ICIALLU, 0x8000000d, 0, 0x4c}, - {SCORPION_IMPL_ICIALLU, 0x80000d00, 0, 0x4d}, - {SCORPION_NONICIALLU_BTAC_INV, 0x800d0000, 0, 0x4e}, - {SCORPION_ICIMVAU_IMPL_ICIALLU, 0x8d000000, 0, 0x4f}, - - {SCORPION_SPIPE_ONLY_CYCLES, 0x80000600, 1, 0x51}, - {SCORPION_XPIPE_ONLY_CYCLES, 0x80060000, 1, 0x52}, - {SCORPION_DUAL_CYCLES, 0x86000000, 1, 0x53}, - {SCORPION_DISPATCH_ANY_CYCLES, 0x89000000, 1, 0x53}, - {SCORPION_FIFO_FULLBLK_CMT, 0x8000000d, 1, 0x50}, - {SCORPION_FAIL_COND_INST, 0x800d0000, 1, 0x52}, - {SCORPION_PASS_COND_INST, 0x8d000000, 1, 0x53}, - {SCORPION_ALLOW_VU_CLK, 0x8000000e, 1, 0x50}, - {SCORPION_VU_IDLE, 0x80000e00, 1, 0x51}, - {SCORPION_ALLOW_L2_CLK, 0x800e0000, 1, 0x52}, - {SCORPION_L2_IDLE, 0x8e000000, 1, 0x53}, - - {SCORPION_DTLB_IMPL_INV_SCTLR_DACR, 0x80000001, 2, 0x54}, - {SCORPION_DTLB_EXPL_INV, 0x80000100, 2, 0x55}, - {SCORPION_DTLB_MISS, 0x80010000, 2, 0x56}, - {SCORPION_DTLB_ACCESS, 0x81000000, 2, 0x57}, - {SCORPION_ITLB_MISS, 0x80000200, 2, 0x55}, - {SCORPION_ITLB_IMPL_INV, 0x80020000, 2, 0x56}, - {SCORPION_ITLB_EXPL_INV, 0x82000000, 2, 0x57}, - {SCORPION_UTLB_D_MISS, 0x80000003, 2, 0x54}, - {SCORPION_UTLB_D_ACCESS, 0x80000300, 2, 0x55}, - {SCORPION_UTLB_I_MISS, 0x80030000, 2, 0x56}, - {SCORPION_UTLB_I_ACCESS, 0x83000000, 2, 0x57}, - {SCORPION_UTLB_INV_ASID, 0x80000400, 2, 0x55}, - {SCORPION_UTLB_INV_MVA, 0x80040000, 2, 0x56}, - {SCORPION_UTLB_INV_ALL, 0x84000000, 2, 0x57}, - {SCORPION_S2_HOLD_RDQ_UNAVAIL, 0x80000800, 2, 0x55}, - {SCORPION_S2_HOLD, 0x88000000, 2, 0x57}, - {SCORPION_S2_HOLD_DEV_OP, 0x80000900, 2, 0x55}, - {SCORPION_S2_HOLD_ORDER, 0x80090000, 2, 0x56}, - {SCORPION_S2_HOLD_BARRIER, 0x89000000, 2, 0x57}, - - {SCORPION_VIU_DUAL_CYCLE, 0x80000001, 4, 0x5c}, - {SCORPION_VIU_SINGLE_CYCLE, 0x80000100, 4, 0x5d}, - {SCORPION_VX_PIPE_WAR_STALL_CYCLES, 0x80000005, 4, 0x5c}, - {SCORPION_VX_PIPE_WAW_STALL_CYCLES, 0x80000500, 4, 0x5d}, - {SCORPION_VX_PIPE_RAW_STALL_CYCLES, 0x80050000, 4, 0x5e}, - {SCORPION_VX_PIPE_LOAD_USE_STALL, 0x80000007, 4, 0x5c}, - {SCORPION_VS_PIPE_WAR_STALL_CYCLES, 0x80000008, 4, 0x5c}, - {SCORPION_VS_PIPE_WAW_STALL_CYCLES, 0x80000800, 4, 0x5d}, - {SCORPION_VS_PIPE_RAW_STALL_CYCLES, 0x80080000, 4, 0x5e}, - {SCORPION_EXCEPTIONS_INV_OPERATION, 0x8000000b, 4, 0x5c}, - {SCORPION_EXCEPTIONS_DIV_BY_ZERO, 0x80000b00, 4, 0x5d}, - {SCORPION_COND_INST_FAIL_VX_PIPE, 0x800b0000, 4, 0x5e}, - {SCORPION_COND_INST_FAIL_VS_PIPE, 0x8b000000, 4, 0x5f}, - {SCORPION_EXCEPTIONS_OVERFLOW, 0x8000000c, 4, 0x5c}, - {SCORPION_EXCEPTIONS_UNDERFLOW, 0x80000c00, 4, 0x5d}, - {SCORPION_EXCEPTIONS_DENORM, 0x8c000000, 4, 0x5f}, - -#ifdef CONFIG_ARCH_MSM_SCORPIONMP - {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}, - {SCORPION_BANK_CD_HIT, 0x80010000, 3, 0x5a}, - {SCORPION_BANK_CD_ACCESS, 0x81000000, 3, 0x5b}, - {SCORPION_BANK_AB_DSIDE_HIT, 0x80000002, 3, 0x58}, - {SCORPION_BANK_AB_DSIDE_ACCESS, 0x80000200, 3, 0x59}, - {SCORPION_BANK_CD_DSIDE_HIT, 0x80020000, 3, 0x5a}, - {SCORPION_BANK_CD_DSIDE_ACCESS, 0x82000000, 3, 0x5b}, - {SCORPION_BANK_AB_ISIDE_HIT, 0x80000003, 3, 0x58}, - {SCORPION_BANK_AB_ISIDE_ACCESS, 0x80000300, 3, 0x59}, - {SCORPION_BANK_CD_ISIDE_HIT, 0x80030000, 3, 0x5a}, - {SCORPION_BANK_CD_ISIDE_ACCESS, 0x83000000, 3, 0x5b}, - {SCORPION_ISIDE_RD_WAIT, 0x80000009, 3, 0x58}, - {SCORPION_DSIDE_RD_WAIT, 0x80090000, 3, 0x5a}, - {SCORPION_BANK_BYPASS_WRITE, 0x8000000a, 3, 0x58}, - {SCORPION_BANK_AB_NON_CASTOUT, 0x8000000c, 3, 0x58}, - {SCORPION_BANK_AB_L2_CASTOUT, 0x80000c00, 3, 0x59}, - {SCORPION_BANK_CD_NON_CASTOUT, 0x800c0000, 3, 0x5a}, - {SCORPION_BANK_CD_L2_CASTOUT, 0x8c000000, 3, 0x5b}, -#endif -}; - -static inline void scorpion_pmnc_write(u32 val) -{ - val &= PMNC_MASK; - asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (val)); -} - -static inline u32 scorpion_pmnc_read(void) -{ - u32 val; - asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val)); - return val; -} - -static inline u32 scorpion_ccnt_read(void) -{ - u32 val; - asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val)); - return val; -} - -static inline u32 scorpion_cntn_read(void) -{ - u32 val; - asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val)); - return val; -} - -static inline u32 scorpion_pmnc_enable_counter(unsigned int cnt) -{ - u32 val; - - if (cnt >= CNTMAX) { - pr_err("gator: CPU%u enabling wrong PMNC counter %d\n", smp_processor_id(), cnt); - return -1; - } - - if (cnt == CCNT) - val = CCNT_REG; - else - val = (1 << (cnt - CNT0)); - - asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val)); - - return cnt; -} - -static inline u32 scorpion_pmnc_disable_counter(unsigned int cnt) -{ - u32 val; - - if (cnt >= CNTMAX) { - pr_err("gator: CPU%u disabling wrong PMNC counter %d\n", smp_processor_id(), cnt); - return -1; - } - - if (cnt == CCNT) - val = CCNT_REG; - else - val = (1 << (cnt - CNT0)); - - asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val)); - - return cnt; -} - -static inline int scorpion_pmnc_select_counter(unsigned int cnt) -{ - u32 val; - - if ((cnt == CCNT) || (cnt >= CNTMAX)) { - pr_err("gator: CPU%u selecting wrong PMNC counter %d\n", smp_processor_id(), cnt); - return -1; - } - - val = (cnt - CNT0); - asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val)); - - return cnt; -} - -static u32 scorpion_read_lpm0(void) -{ - u32 val; - asm volatile("mrc p15, 0, %0, c15, c0, 0" : "=r" (val)); - return val; -} - -static void scorpion_write_lpm0(u32 val) -{ - asm volatile("mcr p15, 0, %0, c15, c0, 0" : : "r" (val)); -} - -static u32 scorpion_read_lpm1(void) -{ - u32 val; - asm volatile("mrc p15, 1, %0, c15, c0, 0" : "=r" (val)); - return val; -} - -static void scorpion_write_lpm1(u32 val) -{ - asm volatile("mcr p15, 1, %0, c15, c0, 0" : : "r" (val)); -} - -static u32 scorpion_read_lpm2(void) -{ - u32 val; - asm volatile("mrc p15, 2, %0, c15, c0, 0" : "=r" (val)); - return val; -} - -static void scorpion_write_lpm2(u32 val) -{ - asm volatile("mcr p15, 2, %0, c15, c0, 0" : : "r" (val)); -} - -static u32 scorpion_read_l2lpm(void) -{ - u32 val; - asm volatile("mrc p15, 3, %0, c15, c2, 0" : "=r" (val)); - return val; -} - -static void scorpion_write_l2lpm(u32 val) -{ - asm volatile("mcr p15, 3, %0, c15, c2, 0" : : "r" (val)); -} - -static u32 scorpion_read_vlpm(void) -{ - u32 val; - asm volatile("mrc p10, 7, %0, c11, c0, 0" : "=r" (val)); - return val; -} - -static void scorpion_write_vlpm(u32 val) -{ - asm volatile("mcr p10, 7, %0, c11, c0, 0" : : "r" (val)); -} - -struct scorpion_access_funcs { - u32 (*read) (void); - void (*write) (u32); -}; - -struct scorpion_access_funcs scor_func[] = { - {scorpion_read_lpm0, scorpion_write_lpm0}, - {scorpion_read_lpm1, scorpion_write_lpm1}, - {scorpion_read_lpm2, scorpion_write_lpm2}, - {scorpion_read_l2lpm, scorpion_write_l2lpm}, - {scorpion_read_vlpm, scorpion_write_vlpm}, -}; - -u32 venum_orig_val; -u32 fp_orig_val; - -static void scorpion_pre_vlpm(void) -{ - u32 venum_new_val; - u32 fp_new_val; - - /* 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)); - /* Enable FPEXC */ - asm volatile("mrc p10, 7, %0, c8, c0, 0" : "=r" (fp_orig_val)); - fp_new_val = fp_orig_val | 0x40000000; - asm volatile("mcr p10, 7, %0, c8, c0, 0" : : "r" (fp_new_val)); -} - -static void scorpion_post_vlpm(void) -{ - /* Restore FPEXC*/ - asm volatile("mcr p10, 7, %0, c8, c0, 0" : : "r" (fp_orig_val)); - /* Restore CPACR*/ - asm volatile("mcr p15, 0, %0, c1, c0, 2" : : "r" (venum_orig_val)); -} - -#define COLMN0MASK 0x000000ff -#define COLMN1MASK 0x0000ff00 -#define COLMN2MASK 0x00ff0000 -static u32 scorpion_get_columnmask(u32 setval) -{ - if (setval & COLMN0MASK) - return 0xffffff00; - else if (setval & COLMN1MASK) - return 0xffff00ff; - else if (setval & COLMN2MASK) - return 0xff00ffff; - else - return 0x80ffffff; -} - -static void scorpion_evt_setup(u32 gr, u32 setval) -{ - u32 val; - if (gr == 4) - scorpion_pre_vlpm(); - val = scorpion_get_columnmask(setval) & scor_func[gr].read(); - val = val | setval; - scor_func[gr].write(val); - if (gr == 4) - scorpion_post_vlpm(); -} - -static int get_scorpion_evtinfo(unsigned int evt_type, struct scorp_evt *evtinfo) -{ - u32 idx; - if ((evt_type < 0x4c) || (evt_type >= MSM_MAX_EVT)) - return 0; - idx = evt_type - 0x4c; - if (sc_evt[idx].evt_type == evt_type) { - evtinfo->val = sc_evt[idx].val; - evtinfo->grp = sc_evt[idx].grp; - evtinfo->evt_type_act = sc_evt[idx].evt_type_act; - return 1; - } - return 0; -} - -static inline void scorpion_pmnc_write_evtsel(unsigned int cnt, u32 val) -{ - if (scorpion_pmnc_select_counter(cnt) == cnt) { - if (val < 0x40) { - asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val)); - } else { - 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; - 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); - } - } -} - -static void scorpion_pmnc_reset_counter(unsigned int cnt) -{ - u32 val = 0; - - if (cnt == CCNT) { - scorpion_pmnc_disable_counter(cnt); - - asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (val)); - - if (pmnc_enabled[cnt] != 0) - scorpion_pmnc_enable_counter(cnt); - - } else if (cnt >= CNTMAX) { - pr_err("gator: CPU%u resetting wrong PMNC counter %d\n", smp_processor_id(), cnt); - } else { - scorpion_pmnc_disable_counter(cnt); - - if (scorpion_pmnc_select_counter(cnt) == cnt) - asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (val)); - - if (pmnc_enabled[cnt] != 0) - scorpion_pmnc_enable_counter(cnt); - } -} - -static int gator_events_scorpion_create_files(struct super_block *sb, struct dentry *root) -{ - struct dentry *dir; - int i; - - for (i = 0; i < pmnc_counters; i++) { - char buf[40]; - if (i == 0) { - snprintf(buf, sizeof buf, "%s_ccnt", pmnc_name); - } else { - 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]); - if (i > 0) { - gatorfs_create_ulong(sb, dir, "event", &pmnc_event[i]); - } - } - - return 0; -} - -static int gator_events_scorpion_online(int** buffer) -{ - unsigned int cnt, len = 0, cpu = smp_processor_id(); - - if (scorpion_pmnc_read() & PMNC_E) { - scorpion_pmnc_write(scorpion_pmnc_read() & ~PMNC_E); - } - - /* Initialize & Reset PMNC: C bit and P bit */ - scorpion_pmnc_write(PMNC_P | PMNC_C); - - for (cnt = CCNT; cnt < CNTMAX; cnt++) { - unsigned long event; - - per_cpu(perfPrev, smp_processor_id())[cnt] = 0; - - if (!pmnc_enabled[cnt]) - continue; - - // disable counter - scorpion_pmnc_disable_counter(cnt); - - event = pmnc_event[cnt] & 255; - - // Set event (if destined for PMNx counters), We don't need to set the event if it's a cycle count - if (cnt != CCNT) - scorpion_pmnc_write_evtsel(cnt, event); - - // reset counter - scorpion_pmnc_reset_counter(cnt); - - // Enable counter, do not enable interrupt for this counter - scorpion_pmnc_enable_counter(cnt); - } - - // enable - scorpion_pmnc_write(scorpion_pmnc_read() | PMNC_E); - - // 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(); - } else if (scorpion_pmnc_select_counter(cnt) == cnt) { - value = scorpion_cntn_read(); - } else { - value = 0; - } - scorpion_pmnc_reset_counter(cnt); - per_cpu(perfPrev, cpu)[cnt] = 0; - per_cpu(perfCnt, cpu)[len++] = pmnc_key[cnt]; - per_cpu(perfCnt, cpu)[len++] = 0; - } - } - - if (buffer) - *buffer = per_cpu(perfCnt, cpu); - - return len; -} - -static int gator_events_scorpion_offline(int** buffer) -{ - scorpion_pmnc_write(scorpion_pmnc_read() & ~PMNC_E); - return 0; -} - -static void gator_events_scorpion_stop(void) -{ - unsigned int cnt; - - for (cnt = CCNT; cnt < CNTMAX; cnt++) { - pmnc_enabled[cnt] = 0; - pmnc_event[cnt] = 0; - } -} - -static int gator_events_scorpion_read(int **buffer) -{ - int cnt, len = 0; - int cpu = smp_processor_id(); - - for (cnt = 0; cnt < pmnc_counters; cnt++) { - if (pmnc_enabled[cnt]) { - int value; - if (cnt == CCNT) { - value = scorpion_ccnt_read(); - } else if (scorpion_pmnc_select_counter(cnt) == cnt) { - value = scorpion_cntn_read(); - } else { - value = 0; - } - scorpion_pmnc_reset_counter(cnt); - if (value != per_cpu(perfPrev, cpu)[cnt]) { - per_cpu(perfPrev, cpu)[cnt] = value; - per_cpu(perfCnt, cpu)[len++] = pmnc_key[cnt]; - per_cpu(perfCnt, cpu)[len++] = value; - } - } - } - - if (buffer) - *buffer = per_cpu(perfCnt, cpu); - - return len; -} - -static struct gator_interface gator_events_scorpion_interface = { - .create_files = gator_events_scorpion_create_files, - .stop = gator_events_scorpion_stop, - .online = gator_events_scorpion_online, - .offline = gator_events_scorpion_offline, - .read = gator_events_scorpion_read, -}; - -int gator_events_scorpion_init(void) -{ - unsigned int cnt; - - switch (gator_cpuid()) { - case SCORPION: - pmnc_name = "Scorpion"; - pmnc_counters = 4; - break; - case SCORPIONMP: - pmnc_name = "ScorpionMP"; - pmnc_counters = 4; - break; - default: - return -1; - } - - pmnc_counters++; // CNT[n] + CCNT - - for (cnt = CCNT; cnt < CNTMAX; cnt++) { - pmnc_enabled[cnt] = 0; - pmnc_event[cnt] = 0; - pmnc_key[cnt] = gator_events_get_key(); - } - - return gator_events_install(&gator_events_scorpion_interface); -} - -gator_events_init(gator_events_scorpion_init); - -#else -int gator_events_scorpion_init(void) -{ - return -1; -} -#endif diff --git a/drivers/gator/driver/gator_fs.c b/drivers/gator/driver/gator_fs.c deleted file mode 100644 index 8277c3aac3e..00000000000 --- a/drivers/gator/driver/gator_fs.c +++ /dev/null @@ -1,284 +0,0 @@ -/** - * @file gatorfs.c - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * - * A simple filesystem for configuration and - * access of oprofile. - */ - -#include -#include -#include -#include -#include - -#define gatorfs_MAGIC 0x24051020 -#define TMPBUFSIZE 50 -DEFINE_SPINLOCK(gatorfs_lock); - -static struct inode *gatorfs_get_inode(struct super_block *sb, int mode) -{ - struct inode *inode = new_inode(sb); - - if (inode) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) - inode->i_ino = get_next_ino(); -#endif - inode->i_mode = mode; - inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; - } - return inode; -} - -static const struct super_operations s_ops = { - .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) -{ - return simple_read_from_buffer(buf, count, offset, str, strlen(str)); -} - -ssize_t gatorfs_ulong_to_user(unsigned long val, char __user *buf, size_t count, loff_t *offset) -{ - char tmpbuf[TMPBUFSIZE]; - size_t maxlen = snprintf(tmpbuf, TMPBUFSIZE, "%lu\n", val); - if (maxlen > TMPBUFSIZE) - maxlen = TMPBUFSIZE; - return simple_read_from_buffer(buf, count, offset, tmpbuf, maxlen); -} - -int gatorfs_ulong_from_user(unsigned long *val, char const __user *buf, size_t count) -{ - char tmpbuf[TMPBUFSIZE]; - unsigned long flags; - - if (!count) - return 0; - - if (count > TMPBUFSIZE - 1) - return -EINVAL; - - memset(tmpbuf, 0x0, TMPBUFSIZE); - - if (copy_from_user(tmpbuf, buf, count)) - return -EFAULT; - - spin_lock_irqsave(&gatorfs_lock, flags); - *val = simple_strtoul(tmpbuf, NULL, 0); - spin_unlock_irqrestore(&gatorfs_lock, flags); - return 0; -} - -static ssize_t ulong_read_file(struct file *file, char __user *buf, size_t count, loff_t *offset) -{ - unsigned long *val = file->private_data; - return gatorfs_ulong_to_user(*val, buf, count, offset); -} - -static ssize_t ulong_write_file(struct file *file, char const __user *buf, size_t count, loff_t *offset) -{ - unsigned long *value = file->private_data; - int retval; - - if (*offset) - return -EINVAL; - - retval = gatorfs_ulong_from_user(value, buf, count); - - if (retval) - return retval; - return count; -} - -static int default_open(struct inode *inode, struct file *filp) -{ - if (inode->i_private) - filp->private_data = inode->i_private; - return 0; -} - -static const struct file_operations ulong_fops = { - .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, -}; - -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 *dentry; - struct inode *inode; - - dentry = d_alloc_name(root, name); - if (!dentry) - return NULL; - inode = gatorfs_get_inode(sb, S_IFREG | perm); - if (!inode) { - dput(dentry); - return NULL; - } - inode->i_fop = fops; - d_add(dentry, inode); - return dentry; -} - -int gatorfs_create_ulong(struct super_block *sb, struct dentry *root, - char const *name, unsigned long *val) -{ - struct dentry *d = __gatorfs_create_file(sb, root, name, - &ulong_fops, 0644); - if (!d) - return -EFAULT; - - d->d_inode->i_private = val; - return 0; -} - -int gatorfs_create_ro_ulong(struct super_block *sb, struct dentry *root, - char const *name, unsigned long *val) -{ - struct dentry *d = __gatorfs_create_file(sb, root, name, - &ulong_ro_fops, 0444); - if (!d) - return -EFAULT; - - d->d_inode->i_private = val; - return 0; -} - -static ssize_t atomic_read_file(struct file *file, char __user *buf, size_t count, loff_t *offset) -{ - atomic_t *val = file->private_data; - return gatorfs_ulong_to_user(atomic_read(val), buf, count, offset); -} - -static const struct file_operations atomic_ro_fops = { - .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) -{ - struct dentry *d = __gatorfs_create_file(sb, root, name, - &atomic_ro_fops, 0444); - if (!d) - return -EFAULT; - - d->d_inode->i_private = val; - return 0; -} - -int gatorfs_create_file(struct super_block *sb, struct dentry *root, - char const *name, const struct file_operations *fops) -{ - if (!__gatorfs_create_file(sb, root, name, fops, 0644)) - return -EFAULT; - return 0; -} - -int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root, - char const *name, const struct file_operations *fops, int perm) -{ - if (!__gatorfs_create_file(sb, root, name, fops, perm)) - return -EFAULT; - return 0; -} - -struct dentry *gatorfs_mkdir(struct super_block *sb, - struct dentry *root, char const *name) -{ - struct dentry *dentry; - struct inode *inode; - - dentry = d_alloc_name(root, name); - if (!dentry) - return NULL; - inode = gatorfs_get_inode(sb, S_IFDIR | 0755); - if (!inode) { - dput(dentry); - return NULL; - } - inode->i_op = &simple_dir_inode_operations; - inode->i_fop = &simple_dir_operations; - d_add(dentry, inode); - return dentry; -} - -static int gatorfs_fill_super(struct super_block *sb, void *data, int silent) -{ - struct inode *root_inode; - struct dentry *root_dentry; - - sb->s_blocksize = PAGE_CACHE_SIZE; - sb->s_blocksize_bits = PAGE_CACHE_SHIFT; - sb->s_magic = gatorfs_MAGIC; - sb->s_op = &s_ops; - sb->s_time_gran = 1; - - root_inode = gatorfs_get_inode(sb, S_IFDIR | 0755); - if (!root_inode) - return -ENOMEM; - root_inode->i_op = &simple_dir_inode_operations; - root_inode->i_fop = &simple_dir_operations; - root_dentry = d_alloc_root(root_inode); - if (!root_dentry) { - iput(root_inode); - return -ENOMEM; - } - - sb->s_root = root_dentry; - - gator_op_create_files(sb, root_dentry); - - // FIXME: verify kill_litter_super removes our dentries - return 0; -} - -#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) -{ - 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) -{ - return mount_nodev(fs_type, flags, data, gatorfs_fill_super); -} -#endif - -static struct file_system_type gatorfs_type = { - .owner = THIS_MODULE, - .name = "gatorfs", -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39) - .get_sb = gatorfs_get_sb, -#else - .mount = gatorfs_mount, -#endif - - .kill_sb = kill_litter_super, -}; - -int __init gatorfs_register(void) -{ - return register_filesystem(&gatorfs_type); -} - -void gatorfs_unregister(void) -{ - unregister_filesystem(&gatorfs_type); -} diff --git a/drivers/gator/driver/gator_hrtimer_gator.c b/drivers/gator/driver/gator_hrtimer_gator.c deleted file mode 100644 index 5896b3c39ae..00000000000 --- a/drivers/gator/driver/gator_hrtimer_gator.c +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Copyright (C) ARM Limited 2011-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. - * - */ - -// gator_hrtimer_perf.c is used if perf is supported -// update, gator_hrtimer_gator.c always used until issues resolved with perf hrtimers -#if 1 - -void (*callback)(void); -DEFINE_PER_CPU(struct hrtimer, percpu_hrtimer); -static ktime_t profiling_interval; -static void gator_hrtimer_online(int cpu); -static void gator_hrtimer_offline(int cpu); - -static enum hrtimer_restart gator_hrtimer_notify(struct hrtimer *hrtimer) -{ - hrtimer_forward_now(hrtimer, profiling_interval); - (*callback)(); - return HRTIMER_RESTART; -} - -static void gator_hrtimer_switch_cpus_online(void *unused) -{ - gator_hrtimer_online(smp_processor_id()); -} - -static void gator_hrtimer_online(int cpu) -{ - struct hrtimer *hrtimer = &per_cpu(percpu_hrtimer, cpu); - if (cpu != smp_processor_id()) { - smp_call_function_single(cpu, gator_hrtimer_switch_cpus_online, NULL, 1); - return; - } - - hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - hrtimer->function = gator_hrtimer_notify; - hrtimer_start(hrtimer, profiling_interval, HRTIMER_MODE_REL_PINNED); -} - -static void gator_hrtimer_switch_cpus_offline(void *unused) -{ - gator_hrtimer_offline(smp_processor_id()); -} - -static void gator_hrtimer_offline(int cpu) -{ - struct hrtimer *hrtimer = &per_cpu(percpu_hrtimer, cpu); - if (cpu != smp_processor_id()) { - smp_call_function_single(cpu, gator_hrtimer_switch_cpus_offline, NULL, 1); - return; - } - - hrtimer_cancel(hrtimer); -} - -static int gator_hrtimer_init(int interval, void (*func)(void)) -{ - (callback) = (func); - - // calculate profiling interval - profiling_interval = ns_to_ktime(1000000000UL / interval); - - return 0; -} - -static void gator_hrtimer_shutdown(void) -{ - /* empty */ -} - -#endif diff --git a/drivers/gator/driver/gator_hrtimer_perf.c b/drivers/gator/driver/gator_hrtimer_perf.c deleted file mode 100644 index 7c0333f6445..00000000000 --- a/drivers/gator/driver/gator_hrtimer_perf.c +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Copyright (C) ARM Limited 2011-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. - * - */ - -// gator_hrtimer_gator.c is used if perf is not supported -// update, gator_hrtimer_gator.c always used until issues resolved with perf hrtimers -#if 0 - -// Note: perf Cortex support added in 2.6.35 and PERF_COUNT_SW_CPU_CLOCK/hrtimer broken on 2.6.35 and 2.6.36 -// not relevant as this code is not active until 3.0.0, but wanted to document the issue - -void (*callback)(void); -static int profiling_interval; -static DEFINE_PER_CPU(struct perf_event *, perf_hrtimer); -static DEFINE_PER_CPU(struct perf_event_attr *, perf_hrtimer_attr); - -static void gator_hrtimer_shutdown(void); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) -static void hrtimer_overflow_handler(struct perf_event *event, int unused, struct perf_sample_data *data, struct pt_regs *regs) -#else -static void hrtimer_overflow_handler(struct perf_event *event, struct perf_sample_data *data, struct pt_regs *regs) -#endif -{ - (*callback)(); -} - -static int gator_online_single_hrtimer(int cpu) -{ - if (per_cpu(perf_hrtimer, cpu) != 0 || per_cpu(perf_hrtimer_attr, cpu) == 0) - return 0; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) - per_cpu(perf_hrtimer, cpu) = perf_event_create_kernel_counter(per_cpu(perf_hrtimer_attr, cpu), cpu, 0, hrtimer_overflow_handler); -#else - per_cpu(perf_hrtimer, cpu) = perf_event_create_kernel_counter(per_cpu(perf_hrtimer_attr, cpu), cpu, 0, hrtimer_overflow_handler, 0); -#endif - if (IS_ERR(per_cpu(perf_hrtimer, cpu))) { - per_cpu(perf_hrtimer, cpu) = NULL; - return -1; - } - - if (per_cpu(perf_hrtimer, cpu)->state != PERF_EVENT_STATE_ACTIVE) { - perf_event_release_kernel(per_cpu(perf_hrtimer, cpu)); - per_cpu(perf_hrtimer, cpu) = NULL; - return -1; - } - - return 0; -} - -static void gator_hrtimer_online(int cpu) -{ - if (gator_online_single_hrtimer(cpu) < 0) { - pr_debug("gator: unable to online the hrtimer on cpu%d\n", cpu); - } -} - -static void gator_hrtimer_offline(int cpu) -{ - if (per_cpu(perf_hrtimer, cpu)) { - perf_event_release_kernel(per_cpu(perf_hrtimer, cpu)); - per_cpu(perf_hrtimer, cpu) = NULL; - } -} - -static int gator_hrtimer_init(int interval, void (*func)(void)) -{ - u32 size = sizeof(struct perf_event_attr); - int cpu; - - callback = func; - - // calculate profiling interval - profiling_interval = 1000000000 / interval; - - for_each_present_cpu(cpu) { - per_cpu(perf_hrtimer, cpu) = 0; - per_cpu(perf_hrtimer_attr, cpu) = kmalloc(size, GFP_KERNEL); - if (per_cpu(perf_hrtimer_attr, cpu) == 0) { - gator_hrtimer_shutdown(); - return -1; - } - - memset(per_cpu(perf_hrtimer_attr, cpu), 0, size); - per_cpu(perf_hrtimer_attr, cpu)->type = PERF_TYPE_SOFTWARE; - per_cpu(perf_hrtimer_attr, cpu)->size = size; - per_cpu(perf_hrtimer_attr, cpu)->config = PERF_COUNT_SW_CPU_CLOCK; - per_cpu(perf_hrtimer_attr, cpu)->sample_period = profiling_interval; - per_cpu(perf_hrtimer_attr, cpu)->pinned = 1; - } - - return 0; -} - -static void gator_hrtimer_shutdown(void) -{ - int cpu; - - for_each_present_cpu(cpu) { - if (per_cpu(perf_hrtimer_attr, cpu)) { - kfree(per_cpu(perf_hrtimer_attr, cpu)); - per_cpu(perf_hrtimer_attr, cpu) = NULL; - } - } -} - -#endif diff --git a/drivers/gator/driver/gator_main.c b/drivers/gator/driver/gator_main.c deleted file mode 100644 index 6341ef6f051..00000000000 --- a/drivers/gator/driver/gator_main.c +++ /dev/null @@ -1,1109 +0,0 @@ -/** - * 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. - * - */ - -static unsigned long gator_protocol_version = 8; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gator.h" -#include "gator_events.h" - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) -#error kernels prior to 2.6.32 are not supported -#endif - -#if !defined(CONFIG_GENERIC_TRACER) && !defined(CONFIG_TRACING) -#error gator requires the kernel to have CONFIG_GENERIC_TRACER or CONFIG_TRACING defined -#endif - -#ifndef CONFIG_PROFILING -#error gator requires the kernel to have CONFIG_PROFILING defined -#endif - -#ifndef CONFIG_HIGH_RES_TIMERS -#error gator requires the kernel to have CONFIG_HIGH_RES_TIMERS defined -#endif - -#if defined(__arm__) && defined(CONFIG_SMP) && !defined(CONFIG_LOCAL_TIMERS) -#error gator requires the kernel to have CONFIG_LOCAL_TIMERS defined on SMP systems -#endif - -#if (GATOR_PERF_SUPPORT) && (!(GATOR_PERF_PMU_SUPPORT)) -#ifndef CONFIG_PERF_EVENTS -#warning gator requires the kernel to have CONFIG_PERF_EVENTS defined to support pmu hardware counters -#elif !defined CONFIG_HW_PERF_EVENTS -#warning gator requires the kernel to have CONFIG_HW_PERF_EVENTS defined to support pmu hardware counters -#endif -#endif - -#if (!(GATOR_CPU_FREQ_SUPPORT)) -#warning gator requires kernel version 2.6.38 or greater and CONFIG_CPU_FREQ defined in order to enable the CPU Freq timeline chart -#endif - -/****************************************************************************** - * DEFINES - ******************************************************************************/ -#define TIMER_BUFFER_SIZE_DEFAULT (512*1024) -#define EVENT_BUFFER_SIZE_DEFAULT (128*1024) - -#define NO_COOKIE 0UL -#define INVALID_COOKIE ~0UL - -#define FRAME_HRTIMER 1 -#define FRAME_EVENT 2 -#define FRAME_ANNOTATE 3 - -#define MESSAGE_COOKIE 1 -#define MESSAGE_COUNTERS 3 -#define MESSAGE_START_BACKTRACE 5 -#define MESSAGE_END_BACKTRACE 7 -#define MESSAGE_SCHEDULER_TRACE 9 -#define MESSAGE_PID_NAME 11 -#define MESSAGE_GPU_TRACE 13 -#define MESSAGE_OVERFLOW 127 - -#define MAXSIZE_PACK32 5 -#define MAXSIZE_PACK64 9 - -#if defined(__arm__) -#define PC_REG regs->ARM_pc -#else -#define PC_REG regs->ip -#endif - -enum {TIMER_BUF, EVENT_BUF, NUM_GATOR_BUFS}; - -/****************************************************************************** - * Globals - ******************************************************************************/ -static unsigned long gator_cpu_cores; -static unsigned long userspace_buffer_size; -static unsigned long gator_backtrace_depth; - -static unsigned long gator_started; -static unsigned long gator_buffer_opened; -static unsigned long gator_timer_count; -static unsigned long gator_streaming; -static DEFINE_MUTEX(start_mutex); -static DEFINE_MUTEX(gator_buffer_mutex); - -bool event_based_sampling; - -static DECLARE_WAIT_QUEUE_HEAD(gator_buffer_wait); - -static void buffer_check(int cpu, int buftype); - -/****************************************************************************** - * Prototypes - ******************************************************************************/ -static bool buffer_check_space(int cpu, int buftype, int bytes); -static void gator_buffer_write_packed_int(int cpu, int buftype, unsigned int x); -static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long long x); -static void gator_buffer_write_string(int cpu, int buftype, char *x); -static int gator_write_packed_int(char *buffer, unsigned int x); -static int gator_write_packed_int64(char *buffer, unsigned long long x); -static void gator_add_trace(int cpu, int buftype, unsigned int address); -static void gator_add_sample(int cpu, int buftype, struct pt_regs * const regs); -static uint64_t gator_get_time(void); - -static uint32_t gator_buffer_size[NUM_GATOR_BUFS]; -static uint32_t gator_buffer_mask[NUM_GATOR_BUFS]; -static DEFINE_PER_CPU(int[NUM_GATOR_BUFS], gator_buffer_read); -static DEFINE_PER_CPU(int[NUM_GATOR_BUFS], gator_buffer_write); -static DEFINE_PER_CPU(int[NUM_GATOR_BUFS], gator_buffer_commit); -static DEFINE_PER_CPU(int[NUM_GATOR_BUFS], buffer_space_available); -static DEFINE_PER_CPU(char *[NUM_GATOR_BUFS], gator_buffer); -static DEFINE_PER_CPU(uint64_t, emit_overflow); - -/****************************************************************************** - * Application Includes - ******************************************************************************/ -#include "gator_hrtimer_perf.c" -#include "gator_hrtimer_gator.c" -#include "gator_cookies.c" -#include "gator_trace_sched.c" -#include "gator_trace_gpu.c" -#include "gator_backtrace.c" -#include "gator_annotate.c" -#include "gator_fs.c" -#include "gator_ebs.c" -#include "gator_pack.c" - -/****************************************************************************** - * Misc - ******************************************************************************/ -#if defined(__arm__) -u32 gator_cpuid(void) -{ - u32 val; - asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r" (val)); - return (val >> 4) & 0xfff; -} -#endif - -/****************************************************************************** - * Commit interface - ******************************************************************************/ -static bool buffer_commit_ready(int* cpu, int* buftype) -{ - int cpu_x, x; - for_each_present_cpu(cpu_x) { - for (x = 0; x < NUM_GATOR_BUFS; x++) - if (per_cpu(gator_buffer_commit, cpu_x)[x] != per_cpu(gator_buffer_read, cpu_x)[x]) { - *cpu = cpu_x; - *buftype = x; - return true; - } - } - return false; -} - -/****************************************************************************** - * Buffer management - ******************************************************************************/ -static bool buffer_check_space(int cpu, int buftype, int bytes) -{ - int remaining, filled; - - filled = per_cpu(gator_buffer_write, cpu)[buftype] - per_cpu(gator_buffer_read, cpu)[buftype]; - if (filled < 0) { - filled += gator_buffer_size[buftype]; - } - - remaining = gator_buffer_size[buftype] - filled; - - if (per_cpu(buffer_space_available, cpu)[buftype]) { - // Give some extra room; also allows space to insert the overflow error packet - remaining -= 200; - } else { - // Hysteresis, prevents multiple overflow messages - remaining -= 2000; - } - - if (remaining < bytes) { - if (per_cpu(buffer_space_available, cpu)[buftype] == true) { - // overflow packet to be emitted at a later time, as we may be in the middle of writing a message, e.g. counters - per_cpu(emit_overflow, cpu) = gator_get_time(); - pr_err("overflow: remaining = %d\n", gator_buffer_size[buftype] - filled); - } - per_cpu(buffer_space_available, cpu)[buftype] = false; - } else { - per_cpu(buffer_space_available, cpu)[buftype] = true; - } - - return per_cpu(buffer_space_available, cpu)[buftype]; -} - -static void gator_buffer_write_bytes(int cpu, int buftype, char *x, int len) -{ - 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]; - - for (i = 0; i < len; i++) { - buffer[write] = x[i]; - write = (write + 1) & mask; - } - - per_cpu(gator_buffer_write, cpu)[buftype] = write; -} - -static void gator_buffer_write_string(int cpu, int buftype, char *x) -{ - int len = strlen(x); - gator_buffer_write_packed_int(cpu, buftype, len); - gator_buffer_write_bytes(cpu, buftype, x, len); -} - -static void gator_buffer_header(int cpu, int buftype) -{ - int frame; - - if (buftype == TIMER_BUF) - frame = FRAME_HRTIMER; - else if (buftype == EVENT_BUF) - frame = FRAME_EVENT; - else - frame = -1; - - gator_buffer_write_packed_int(cpu, buftype, frame); - gator_buffer_write_packed_int(cpu, buftype, cpu); -} - -static void gator_commit_buffer(int cpu, int buftype) -{ - per_cpu(gator_buffer_commit, cpu)[buftype] = per_cpu(gator_buffer_write, cpu)[buftype]; - gator_buffer_header(cpu, buftype); - wake_up(&gator_buffer_wait); -} - -static void buffer_check(int cpu, int buftype) -{ - int filled = per_cpu(gator_buffer_write, cpu)[buftype] - per_cpu(gator_buffer_commit, cpu)[buftype]; - if (filled < 0) { - filled += gator_buffer_size[buftype]; - } - if (filled >= ((gator_buffer_size[buftype] * 3) / 4)) { - gator_commit_buffer(cpu, buftype); - } -} - -static void gator_add_trace(int cpu, int buftype, unsigned int address) -{ - off_t offset = 0; - unsigned long cookie = get_address_cookie(cpu, buftype, current, address & ~1, &offset); - - if (cookie == NO_COOKIE || cookie == INVALID_COOKIE) { - offset = address; - } - - gator_buffer_write_packed_int(cpu, buftype, offset & ~1); - gator_buffer_write_packed_int(cpu, buftype, cookie); -} - -static void gator_add_sample(int cpu, int buftype, struct pt_regs * const regs) -{ - int inKernel = regs ? !user_mode(regs) : 1; - unsigned long exec_cookie = inKernel ? NO_COOKIE : get_exec_cookie(cpu, buftype, current); - - if (!regs) - return; - - gator_buffer_write_packed_int(cpu, buftype, MESSAGE_START_BACKTRACE); - gator_buffer_write_packed_int64(cpu, buftype, gator_get_time()); - gator_buffer_write_packed_int(cpu, buftype, exec_cookie); - gator_buffer_write_packed_int(cpu, buftype, (unsigned int)current->tgid); - gator_buffer_write_packed_int(cpu, buftype, (unsigned int)current->pid); - gator_buffer_write_packed_int(cpu, buftype, inKernel); - - if (inKernel) { - kernel_backtrace(cpu, buftype, regs); - } else { - // Cookie+PC - gator_add_trace(cpu, buftype, PC_REG); - - // Backtrace - if (gator_backtrace_depth) - arm_backtrace_eabi(cpu, buftype, regs, gator_backtrace_depth); - } - - gator_buffer_write_packed_int(cpu, buftype, MESSAGE_END_BACKTRACE); -} - -/****************************************************************************** - * hrtimer interrupt processing - ******************************************************************************/ -static LIST_HEAD(gator_events); - -static void gator_timer_interrupt(void) -{ - struct pt_regs * const regs = get_irq_regs(); - int cpu = smp_processor_id(); - int *buffer, len, i, buftype = TIMER_BUF; - long long *buffer64; - struct gator_interface *gi; - - // Output scheduler trace - len = gator_trace_sched_read(&buffer64); - if (len > 0 && buffer_check_space(cpu, buftype, len * MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) { - gator_buffer_write_packed_int(cpu, buftype, MESSAGE_SCHEDULER_TRACE); - gator_buffer_write_packed_int(cpu, buftype, len); - for (i = 0; i < len; i++) { - gator_buffer_write_packed_int64(cpu, buftype, buffer64[i]); - } - } - - // Output GPU trace - len = gator_trace_gpu_read(&buffer64); - if (len > 0 && buffer_check_space(cpu, buftype, len * MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) { - gator_buffer_write_packed_int(cpu, buftype, MESSAGE_GPU_TRACE); - gator_buffer_write_packed_int(cpu, buftype, len); - for (i = 0; i < len; i++) { - gator_buffer_write_packed_int64(cpu, buftype, buffer64[i]); - } - } - - // Output counters - if (buffer_check_space(cpu, buftype, MAXSIZE_PACK32 * 2 + MAXSIZE_PACK64)) { - gator_buffer_write_packed_int(cpu, buftype, MESSAGE_COUNTERS); - gator_buffer_write_packed_int64(cpu, buftype, gator_get_time()); - list_for_each_entry(gi, &gator_events, list) { - if (gi->read) { - len = gi->read(&buffer); - if (len > 0 && buffer_check_space(cpu, buftype, len * MAXSIZE_PACK32 + MAXSIZE_PACK32)) { - gator_buffer_write_packed_int(cpu, buftype, len); - for (i = 0; i < len; i++) { - gator_buffer_write_packed_int(cpu, buftype, buffer[i]); - } - } - } else if (gi->read64) { - len = gi->read64(&buffer64); - if (len > 0 && buffer_check_space(cpu, buftype, len * MAXSIZE_PACK64 + MAXSIZE_PACK32)) { - gator_buffer_write_packed_int(cpu, buftype, len); - for (i = 0; i < len; i++) { - gator_buffer_write_packed_int64(cpu, buftype, buffer64[i]); - } - } - } - } - gator_buffer_write_packed_int(cpu, buftype, 0); - } - - // Output backtrace - if (!event_based_sampling && buffer_check_space(cpu, buftype, gator_backtrace_depth * 2 * MAXSIZE_PACK32)) - gator_add_sample(cpu, buftype, regs); - - // Overflow message - if (per_cpu(emit_overflow, cpu)) { - gator_buffer_write_packed_int(cpu, buftype, MESSAGE_OVERFLOW); - gator_buffer_write_packed_int64(cpu, buftype, per_cpu(emit_overflow, cpu)); - per_cpu(emit_overflow, cpu) = 0; - } - - // Check and commit; generally, commit is set to occur once per second - buffer_check(cpu, buftype); -} - -DEFINE_PER_CPU(int, hrtimer_is_active); -static int hrtimer_running; - -// This function runs in interrupt context and on the appropriate core -static void gator_timer_offline(void* unused) -{ - int i, len, cpu = smp_processor_id(); - int* buffer; - long long* buffer64; - - if (per_cpu(hrtimer_is_active, cpu)) { - struct gator_interface *gi; - gator_hrtimer_offline(cpu); - per_cpu(hrtimer_is_active, cpu) = 0; - - // Output scheduler trace - len = gator_trace_sched_offline(&buffer64); - if (len > 0 && buffer_check_space(cpu, TIMER_BUF, len * MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) { - gator_buffer_write_packed_int(cpu, TIMER_BUF, MESSAGE_SCHEDULER_TRACE); - gator_buffer_write_packed_int(cpu, TIMER_BUF, len); - for (i = 0; i < len; i++) { - gator_buffer_write_packed_int64(cpu, TIMER_BUF, buffer64[i]); - } - } - - // Output GPU trace - len = gator_trace_gpu_offline(&buffer64); - if (len > 0 && buffer_check_space(cpu, TIMER_BUF, len * MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) { - gator_buffer_write_packed_int(cpu, TIMER_BUF, MESSAGE_GPU_TRACE); - gator_buffer_write_packed_int(cpu, TIMER_BUF, len); - for (i = 0; i < len; i++) { - gator_buffer_write_packed_int64(cpu, TIMER_BUF, buffer64[i]); - } - } - - // offline any events and output counters - gator_buffer_write_packed_int(cpu, TIMER_BUF, MESSAGE_COUNTERS); - gator_buffer_write_packed_int64(cpu, TIMER_BUF, gator_get_time()); - list_for_each_entry(gi, &gator_events, list) { - if (gi->offline) { - len = gi->offline(&buffer); - if (len > 0 && buffer_check_space(cpu, TIMER_BUF, len * MAXSIZE_PACK32 + MAXSIZE_PACK32)) { - gator_buffer_write_packed_int(cpu, TIMER_BUF, len); - for (i = 0; i < len; i++) - gator_buffer_write_packed_int(cpu, TIMER_BUF, buffer[i]); - } - } - } - gator_buffer_write_packed_int(cpu, TIMER_BUF, 0); - - gator_commit_buffer(cpu, TIMER_BUF); - } - - if (event_based_sampling) { - gator_commit_buffer(cpu, EVENT_BUF); - } -} - -// This function runs in interrupt context and may be running on a core other than core 'cpu' -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); - - gator_event_sampling_offline_dispatch(cpu); -} - -static void gator_timer_stop(void) -{ - int cpu; - - if (hrtimer_running) { - on_each_cpu(gator_timer_offline, NULL, 1); - for_each_online_cpu(cpu) { - gator_timer_offline_dispatch(cpu); - } - - hrtimer_running = 0; - gator_hrtimer_shutdown(); - } -} - -// This function runs in interrupt context and on the appropriate core -static void gator_timer_online(void* unused) -{ - int i, len, cpu = smp_processor_id(); - int* buffer; - - if (!per_cpu(hrtimer_is_active, cpu)) { - struct gator_interface *gi; - - // online any events and output counters - gator_buffer_write_packed_int(cpu, TIMER_BUF, MESSAGE_COUNTERS); - gator_buffer_write_packed_int64(cpu, TIMER_BUF, gator_get_time()); - list_for_each_entry(gi, &gator_events, list) { - if (gi->online) { - len = gi->online(&buffer); - if (len > 0 && buffer_check_space(cpu, TIMER_BUF, len * MAXSIZE_PACK32 + MAXSIZE_PACK32)) { - gator_buffer_write_packed_int(cpu, TIMER_BUF, len); - for (i = 0; i < len; i++) - gator_buffer_write_packed_int(cpu, TIMER_BUF, buffer[i]); - } - } - } - gator_buffer_write_packed_int(cpu, TIMER_BUF, 0); - - gator_event_sampling_online(); - - gator_hrtimer_online(cpu); - per_cpu(hrtimer_is_active, cpu) = 1; - } -} - -// This function runs in interrupt context and may be running on a core other than core 'cpu' -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); - - gator_event_sampling_online_dispatch(cpu); -} - -int gator_timer_start(unsigned long setup) -{ - int cpu; - - if (!setup) { - pr_err("gator: cannot start due to a system tick value of zero\n"); - return -1; - } else if (hrtimer_running) { - pr_notice("gator: high res timer already running\n"); - return 0; - } - - hrtimer_running = 1; - - if (gator_hrtimer_init(setup, gator_timer_interrupt) == -1) - return -1; - - for_each_online_cpu(cpu) { - gator_timer_online_dispatch(cpu); - } - on_each_cpu(gator_timer_online, NULL, 1); - - return 0; -} - -static uint64_t gator_get_time(void) -{ - struct timespec ts; - uint64_t timestamp; - - getnstimeofday(&ts); - timestamp = timespec_to_ns(&ts); - - return timestamp; -} - -/****************************************************************************** - * cpu hotplug and pm notifiers - ******************************************************************************/ -static int __cpuinit gator_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) -{ - 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; - } - - return NOTIFY_OK; -} - -static struct notifier_block __refdata gator_cpu_notifier = { - .notifier_call = gator_cpu_notify, -}; - -// n.b. calling "on_each_cpu" only runs on those that are online -// Registered linux events are not disabled, so their counters will continue to collect -static int gator_pm_notify(struct notifier_block *nb, unsigned long event, void *dummy) -{ - int cpu; - - switch (event) { - case PM_HIBERNATION_PREPARE: - case PM_SUSPEND_PREPARE: - unregister_hotcpu_notifier(&gator_cpu_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_cpu_notifier); - break; - } - - return NOTIFY_OK; -} - -static struct notifier_block gator_pm_notifier = { - .notifier_call = gator_pm_notify, -}; - -static int gator_notifier_start(void) -{ - int retval; - retval = register_hotcpu_notifier(&gator_cpu_notifier); - if (retval == 0) - retval = register_pm_notifier(&gator_pm_notifier); - return retval; -} - -static void gator_notifier_stop(void) -{ - unregister_pm_notifier(&gator_pm_notifier); - unregister_hotcpu_notifier(&gator_cpu_notifier); -} - -/****************************************************************************** - * Main - ******************************************************************************/ -int gator_events_install(struct gator_interface *interface) -{ - list_add_tail(&interface->list, &gator_events); - - return 0; -} - -int gator_events_get_key(void) -{ - static int key; - - return key++; -} - -static int gator_init(void) -{ - int i; - - if (gator_annotate_init()) - return -1; - - // events sources (gator_events.h, generated by gator_events.sh) - for (i = 0; i < ARRAY_SIZE(gator_events_list); i++) - if (gator_events_list[i]) - gator_events_list[i](); - - return 0; -} - -static int gator_start(void) -{ - struct gator_interface *gi; - - // start all events - list_for_each_entry(gi, &gator_events, list) { - if (gi->start && gi->start() != 0) { - struct list_head *ptr = gi->list.prev; - - while (ptr != &gator_events) { - gi = list_entry(ptr, struct gator_interface, list); - - if (gi->stop) - gi->stop(); - - ptr = ptr->prev; - } - goto events_failure; - } - } - - // cookies shall be initialized before trace_sched_start() and gator_timer_start() - if (cookies_initialize()) - goto cookies_failure; - if (gator_annotate_start()) - goto annotate_failure; - if (gator_trace_sched_start()) - goto sched_failure; - if (gator_trace_gpu_start()) - goto gpu_failure; - if (gator_event_sampling_start()) - goto event_sampling_failure; - if (gator_timer_start(gator_timer_count)) - goto timer_failure; - if (gator_notifier_start()) - goto notifier_failure; - - return 0; - -notifier_failure: - gator_timer_stop(); -timer_failure: - gator_event_sampling_stop(); -event_sampling_failure: - gator_trace_gpu_stop(); -gpu_failure: - gator_trace_sched_stop(); -sched_failure: - gator_annotate_stop(); -annotate_failure: - cookies_release(); -cookies_failure: - // stop all events - list_for_each_entry(gi, &gator_events, list) - if (gi->stop) - gi->stop(); -events_failure: - - return -1; -} - -static void gator_stop(void) -{ - struct gator_interface *gi; - - // stop all events - list_for_each_entry(gi, &gator_events, list) - if (gi->stop) - gi->stop(); - - gator_annotate_stop(); - gator_trace_sched_stop(); - gator_trace_gpu_stop(); - gator_event_sampling_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_timer_stop(); -} - -static void gator_exit(void) -{ - gator_annotate_exit(); -} - -/****************************************************************************** - * Filesystem - ******************************************************************************/ -/* fopen("buffer") */ -static int gator_op_setup(void) -{ - int err = 0; - int cpu, i; - - mutex_lock(&start_mutex); - - gator_buffer_size[TIMER_BUF] = userspace_buffer_size; - gator_buffer_mask[TIMER_BUF] = userspace_buffer_size - 1; - - // must be a power of 2 - if (gator_buffer_size[TIMER_BUF] & (gator_buffer_size[TIMER_BUF] - 1)) { - err = -ENOEXEC; - goto setup_error; - } - - gator_buffer_size[EVENT_BUF] = EVENT_BUFFER_SIZE_DEFAULT; - gator_buffer_mask[EVENT_BUF] = gator_buffer_size[EVENT_BUF] - 1; - - // Initialize percpu per buffer variables - for (i = 0; i < NUM_GATOR_BUFS; i++) { - for_each_present_cpu(cpu) { - per_cpu(gator_buffer, cpu)[i] = vmalloc(gator_buffer_size[i]); - if (!per_cpu(gator_buffer, cpu)[i]) { - err = -ENOMEM; - goto setup_error; - } - - per_cpu(gator_buffer_read, cpu)[i] = 0; - per_cpu(gator_buffer_write, cpu)[i] = 0; - per_cpu(gator_buffer_commit, cpu)[i] = 0; - per_cpu(buffer_space_available, cpu)[i] = true; - per_cpu(emit_overflow, cpu) = 0; - gator_buffer_header(cpu, i); - } - } - -setup_error: - mutex_unlock(&start_mutex); - return err; -} - -/* Actually start profiling (echo 1>/dev/gator/driver/enable) */ -static int gator_op_start(void) -{ - int err = 0; - - mutex_lock(&start_mutex); - - if (gator_started || gator_start()) - err = -EINVAL; - else - gator_started = 1; - - mutex_unlock(&start_mutex); - - return err; -} - -/* echo 0>/dev/gator/driver/enable */ -static void gator_op_stop(void) -{ - mutex_lock(&start_mutex); - - if (gator_started) { - gator_stop(); - - mutex_lock(&gator_buffer_mutex); - - gator_started = 0; - cookies_release(); - wake_up(&gator_buffer_wait); - - mutex_unlock(&gator_buffer_mutex); - } - - mutex_unlock(&start_mutex); -} - -static void gator_shutdown(void) -{ - int cpu, i; - - mutex_lock(&start_mutex); - - gator_annotate_shutdown(); - - for_each_present_cpu(cpu) { - mutex_lock(&gator_buffer_mutex); - for (i = 0; i < NUM_GATOR_BUFS; i++) { - vfree(per_cpu(gator_buffer, cpu)[i]); - per_cpu(gator_buffer, cpu)[i] = NULL; - per_cpu(gator_buffer_read, cpu)[i] = 0; - per_cpu(gator_buffer_write, cpu)[i] = 0; - per_cpu(gator_buffer_commit, cpu)[i] = 0; - per_cpu(buffer_space_available, cpu)[i] = true; - per_cpu(emit_overflow, cpu) = 0; - } - mutex_unlock(&gator_buffer_mutex); - } - - mutex_unlock(&start_mutex); -} - -static int gator_set_backtrace(unsigned long val) -{ - int err = 0; - - mutex_lock(&start_mutex); - - if (gator_started) - err = -EBUSY; - else - gator_backtrace_depth = val; - - mutex_unlock(&start_mutex); - - return err; -} - -static ssize_t enable_read(struct file *file, char __user *buf, size_t count, loff_t *offset) -{ - return gatorfs_ulong_to_user(gator_started, buf, count, offset); -} - -static ssize_t enable_write(struct file *file, char const __user *buf, size_t count, loff_t *offset) -{ - unsigned long val; - int retval; - - if (*offset) - return -EINVAL; - - retval = gatorfs_ulong_from_user(&val, buf, count); - if (retval) - return retval; - - if (val) - retval = gator_op_start(); - else - gator_op_stop(); - - if (retval) - return retval; - return count; -} - -static const struct file_operations enable_fops = { - .read = enable_read, - .write = enable_write, -}; - -static int userspace_buffer_open(struct inode *inode, struct file *file) -{ - int err = -EPERM; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (test_and_set_bit_lock(0, &gator_buffer_opened)) - return -EBUSY; - - if ((err = gator_op_setup())) - goto fail; - - /* NB: the actual start happens from userspace - * echo 1 >/dev/gator/driver/enable - */ - - return 0; - -fail: - __clear_bit_unlock(0, &gator_buffer_opened); - return err; -} - -static int userspace_buffer_release(struct inode *inode, struct file *file) -{ - gator_op_stop(); - gator_shutdown(); - __clear_bit_unlock(0, &gator_buffer_opened); - return 0; -} - -static ssize_t userspace_buffer_read(struct file *file, char __user *buf, - size_t count, loff_t *offset) -{ - int retval = -EINVAL; - int commit = 0, length1, length2, read; - char *buffer1; - char *buffer2 = NULL; - int cpu, buftype; - - /* do not handle partial reads */ - if (count != userspace_buffer_size || *offset) - return -EINVAL; - - // sleep until the condition is true or a signal is received - // the condition is checked each time gator_buffer_wait is woken up - buftype = cpu = -1; - wait_event_interruptible(gator_buffer_wait, buffer_commit_ready(&cpu, &buftype) || gator_annotate_ready() || !gator_started); - - if (signal_pending(current)) - return -EINTR; - - length2 = 0; - retval = -EFAULT; - - mutex_lock(&gator_buffer_mutex); - - if (buftype != -1 && cpu != -1) { - read = per_cpu(gator_buffer_read, cpu)[buftype]; - commit = per_cpu(gator_buffer_commit, cpu)[buftype]; - - /* May happen if the buffer is freed during pending reads. */ - if (!per_cpu(gator_buffer, cpu)[buftype]) { - retval = -EFAULT; - goto out; - } - - /* determine the size of two halves */ - length1 = commit - read; - buffer1 = &(per_cpu(gator_buffer, cpu)[buftype][read]); - buffer2 = &(per_cpu(gator_buffer, cpu)[buftype][0]); - if (length1 < 0) { - length1 = gator_buffer_size[buftype] - read; - length2 = commit; - } - } else if (gator_annotate_ready()) { - length1 = gator_annotate_read(&buffer1); - if (!length1) - goto out; - } else { - retval = 0; - goto out; - } - - /* start, middle or end */ - if (length1 > 0) { - if (copy_to_user(&buf[0], buffer1, length1)) { - goto out; - } - } - - /* possible wrap around */ - if (length2 > 0) { - if (copy_to_user(&buf[length1], buffer2, length2)) { - goto out; - } - } - - if (buftype != -1 && cpu != -1) - per_cpu(gator_buffer_read, cpu)[buftype] = commit; - - retval = length1 + length2; - - /* kick just in case we've lost an SMP event */ - wake_up(&gator_buffer_wait); - -out: - mutex_unlock(&gator_buffer_mutex); - return retval; -} - -const struct file_operations gator_event_buffer_fops = { - .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); -} - -static ssize_t depth_write(struct file *file, char const __user *buf, size_t count, loff_t *offset) -{ - unsigned long val; - int retval; - - if (*offset) - return -EINVAL; - - retval = gatorfs_ulong_from_user(&val, buf, count); - if (retval) - return retval; - - retval = gator_set_backtrace(val); - - if (retval) - return retval; - return count; -} - -static const struct file_operations depth_fops = { - .read = depth_read, - .write = depth_write -}; - -void gator_op_create_files(struct super_block *sb, struct dentry *root) -{ - struct dentry *dir; - struct gator_interface *gi; - int cpu; - - /* reinitialize default values */ - gator_cpu_cores = 0; - for_each_present_cpu(cpu) { - gator_cpu_cores++; - } - userspace_buffer_size = TIMER_BUFFER_SIZE_DEFAULT; - gator_streaming = 1; - - gatorfs_create_file(sb, root, "enable", &enable_fops); - gatorfs_create_file(sb, root, "buffer", &gator_event_buffer_fops); - gatorfs_create_file(sb, root, "backtrace_depth", &depth_fops); - gatorfs_create_ulong(sb, root, "cpu_cores", &gator_cpu_cores); - gatorfs_create_ulong(sb, root, "buffer_size", &userspace_buffer_size); - gatorfs_create_ulong(sb, root, "tick", &gator_timer_count); - gatorfs_create_ulong(sb, root, "streaming", &gator_streaming); - gatorfs_create_ro_ulong(sb, root, "version", &gator_protocol_version); - - // Annotate interface - gator_annotate_create_files(sb, 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); -} - -/****************************************************************************** - * Module - ******************************************************************************/ -static int __init gator_module_init(void) -{ - if (gatorfs_register()) { - return -1; - } - - if (gator_init()) { - gatorfs_unregister(); - return -1; - } - - return 0; -} - -static void __exit gator_module_exit(void) -{ - tracepoint_synchronize_unregister(); - gatorfs_unregister(); - gator_exit(); -} - -module_init(gator_module_init); -module_exit(gator_module_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("ARM Ltd"); -MODULE_DESCRIPTION("Gator system profiler"); diff --git a/drivers/gator/driver/gator_pack.c b/drivers/gator/driver/gator_pack.c deleted file mode 100644 index 985e960ad59..00000000000 --- a/drivers/gator/driver/gator_pack.c +++ /dev/null @@ -1,262 +0,0 @@ -/** - * 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. - * - */ - -static void gator_buffer_write_packed_int(int cpu, int buftype, unsigned int x) -{ - uint32_t write = per_cpu(gator_buffer_write, cpu)[buftype]; - uint32_t mask = gator_buffer_mask[buftype]; - char *buffer = per_cpu(gator_buffer, cpu)[buftype]; - int write0 = (write + 0) & mask; - int write1 = (write + 1) & mask; - - if ((x & 0xffffff80) == 0) { - buffer[write0] = x & 0x7f; - per_cpu(gator_buffer_write, cpu)[buftype] = write1; - } else if ((x & 0xffffc000) == 0) { - int write2 = (write + 2) & mask; - buffer[write0] = x | 0x80; - 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; - 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; - per_cpu(gator_buffer_write, cpu)[buftype] = write4; - } else { - int write2 = (write + 2) & mask; - int write3 = (write + 3) & mask; - 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; - per_cpu(gator_buffer_write, cpu)[buftype] = write5; - } -} - -static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long long x) -{ - uint32_t write = per_cpu(gator_buffer_write, cpu)[buftype]; - uint32_t mask = gator_buffer_mask[buftype]; - char *buffer = per_cpu(gator_buffer, cpu)[buftype]; - int write0 = (write + 0) & mask; - int write1 = (write + 1) & mask; - - if ((x & 0xffffffffffffff80LL) == 0) { - buffer[write0] = x & 0x7f; - per_cpu(gator_buffer_write, cpu)[buftype] = write1; - } else if ((x & 0xffffffffffffc000LL) == 0) { - int write2 = (write + 2) & mask; - buffer[write0] = x | 0x80; - 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; - 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; - per_cpu(gator_buffer_write, cpu)[buftype] = write4; - } else if ((x & 0xfffffff800000000LL) == 0) { - int write2 = (write + 2) & mask; - int write3 = (write + 3) & mask; - 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; - per_cpu(gator_buffer_write, cpu)[buftype] = write5; - } else if ((x & 0xfffffc0000000000LL) == 0) { - int write2 = (write + 2) & mask; - int write3 = (write + 3) & mask; - int write4 = (write + 4) & mask; - 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; - per_cpu(gator_buffer_write, cpu)[buftype] = write6; - } else if ((x & 0xfffe000000000000LL) == 0) { - int write2 = (write + 2) & mask; - int write3 = (write + 3) & mask; - int write4 = (write + 4) & mask; - int write5 = (write + 5) & mask; - 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; - per_cpu(gator_buffer_write, cpu)[buftype] = write7; - } else if ((x & 0xff00000000000000LL) == 0) { - int write2 = (write + 2) & mask; - int write3 = (write + 3) & mask; - int write4 = (write + 4) & mask; - int write5 = (write + 5) & mask; - int write6 = (write + 6) & mask; - 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; - per_cpu(gator_buffer_write, cpu)[buftype] = write8; - } else { - int write2 = (write + 2) & mask; - int write3 = (write + 3) & mask; - int write4 = (write + 4) & mask; - int write5 = (write + 5) & mask; - int write6 = (write + 6) & mask; - int write7 = (write + 7) & mask; - 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) & 0xff; - per_cpu(gator_buffer_write, cpu)[buftype] = write9; - } -} - -static int gator_write_packed_int(char *buffer, unsigned int x) -{ - if ((x & 0xffffff80) == 0) { - buffer[0] = x & 0x7f; - return 1; - } else if ((x & 0xffffc000) == 0) { - buffer[0] = x | 0x80; - buffer[1] = (x>>7) & 0x7f; - return 2; - } else if ((x & 0xffe00000) == 0) { - buffer[0] = x | 0x80; - buffer[1] = (x>>7) | 0x80; - buffer[2] = (x>>14) & 0x7f; - return 3; - } else if ((x & 0xf0000000) == 0) { - buffer[0] = x | 0x80; - buffer[1] = (x>>7) | 0x80; - buffer[2] = (x>>14) | 0x80; - buffer[3] = (x>>21) & 0x7f; - return 4; - } else { - buffer[0] = x | 0x80; - buffer[1] = (x>>7) | 0x80; - buffer[2] = (x>>14) | 0x80; - buffer[3] = (x>>21) | 0x80; - buffer[4] = (x>>28) & 0x0f; - return 5; - } -} - -static int gator_write_packed_int64(char *buffer, unsigned long long x) -{ - if ((x & 0xffffffffffffff80LL) == 0) { - buffer[0] = x & 0x7f; - return 1; - } else if ((x & 0xffffffffffffc000LL) == 0) { - buffer[0] = x | 0x80; - buffer[1] = (x>>7) & 0x7f; - return 2; - } else if ((x & 0xffffffffffe00000LL) == 0) { - buffer[0] = x | 0x80; - buffer[1] = (x>>7) | 0x80; - buffer[2] = (x>>14) & 0x7f; - return 3; - } else if ((x & 0xfffffffff0000000LL) == 0) { - buffer[0] = x | 0x80; - buffer[1] = (x>>7) | 0x80; - buffer[2] = (x>>14) | 0x80; - buffer[3] = (x>>21) & 0x7f; - return 4; - } else if ((x & 0xfffffff800000000LL) == 0) { - buffer[0] = x | 0x80; - buffer[1] = (x>>7) | 0x80; - buffer[2] = (x>>14) | 0x80; - buffer[3] = (x>>21) | 0x80; - buffer[4] = (x>>28) & 0x7f; - return 5; - } else if ((x & 0xfffffc0000000000LL) == 0) { - buffer[0] = x | 0x80; - buffer[1] = (x>>7) | 0x80; - buffer[2] = (x>>14) | 0x80; - buffer[3] = (x>>21) | 0x80; - buffer[4] = (x>>28) | 0x80; - buffer[5] = (x>>35) & 0x7f; - return 6; - } else if ((x & 0xfffe000000000000LL) == 0) { - buffer[0] = x | 0x80; - buffer[1] = (x>>7) | 0x80; - buffer[2] = (x>>14) | 0x80; - buffer[3] = (x>>21) | 0x80; - buffer[4] = (x>>28) | 0x80; - buffer[5] = (x>>35) | 0x80; - buffer[6] = (x>>42) & 0x7f; - return 7; - } else if ((x & 0xff00000000000000LL) == 0) { - buffer[0] = x | 0x80; - buffer[1] = (x>>7) | 0x80; - buffer[2] = (x>>14) | 0x80; - buffer[3] = (x>>21) | 0x80; - buffer[4] = (x>>28) | 0x80; - buffer[5] = (x>>35) | 0x80; - buffer[6] = (x>>42) | 0x80; - buffer[7] = (x>>49) & 0x7f; - return 8; - } else { - buffer[0] = x | 0x80; - buffer[1] = (x>>7) | 0x80; - buffer[2] = (x>>14) | 0x80; - buffer[3] = (x>>21) | 0x80; - buffer[4] = (x>>28) | 0x80; - buffer[5] = (x>>35) | 0x80; - buffer[6] = (x>>42) | 0x80; - buffer[7] = (x>>49) | 0x80; - buffer[8] = (x>>56) & 0xff; - return 9; - } -} diff --git a/drivers/gator/driver/gator_trace_gpu.c b/drivers/gator/driver/gator_trace_gpu.c deleted file mode 100644 index bc63995c847..00000000000 --- a/drivers/gator/driver/gator_trace_gpu.c +++ /dev/null @@ -1,250 +0,0 @@ -/** - * 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 "gator.h" - -#include -#include -#include -#include - -#ifdef MALI_SUPPORT -#include "linux/mali_linux_trace.h" -#endif -#include "gator_trace_gpu.h" - -#define ACTIVITY_START 1 -#define ACTIVITY_STOP 2 - -/* Note whether tracepoints have been registered */ -static int mali_trace_registered; -static int gpu_trace_registered; - -#define GPU_OVERFLOW -1 -#define GPU_START 1 -#define GPU_STOP 2 - -#define GPU_UNIT_VP 1 -#define GPU_UNIT_FP 2 - -#define TRACESIZE (8*1024) - -static DEFINE_PER_CPU(uint64_t *[2], theGpuTraceBuf); -static DEFINE_PER_CPU(int, theGpuTraceSel); -static DEFINE_PER_CPU(int, theGpuTracePos); -static DEFINE_PER_CPU(int, theGpuTraceErr); - -int gator_trace_gpu_read(long long **buffer); - -static void probe_gpu_write(int type, int unit, int core, struct task_struct* task) -{ - int tracePos; - unsigned long flags; - uint64_t *traceBuf, time; - int pid, tgid; - int cpu = smp_processor_id(); - - if (!per_cpu(theGpuTraceBuf, cpu)[per_cpu(theGpuTraceSel, cpu)]) - return; - - if (task) { - tgid = (int)task->tgid; - pid = (int)task->pid; - } else { - tgid = pid = 0; - } - - // disable interrupts to synchronize with gator_trace_gpu_read(); spinlocks not needed since percpu buffers are used - local_irq_save(flags); - - time = gator_get_time(); - tracePos = per_cpu(theGpuTracePos, cpu); - traceBuf = per_cpu(theGpuTraceBuf, cpu)[per_cpu(theGpuTraceSel, cpu)]; - - if (tracePos < (TRACESIZE - 100)) { - // capture - traceBuf[tracePos++] = type; - traceBuf[tracePos++] = time; - traceBuf[tracePos++] = unit; - traceBuf[tracePos++] = core; - traceBuf[tracePos++] = tgid; - traceBuf[tracePos++] = pid; - } else if (!per_cpu(theGpuTraceErr, cpu)) { - per_cpu(theGpuTraceErr, cpu) = 1; - traceBuf[tracePos++] = GPU_OVERFLOW; - traceBuf[tracePos++] = time; - traceBuf[tracePos++] = 0; - traceBuf[tracePos++] = 0; - traceBuf[tracePos++] = 0; - traceBuf[tracePos++] = 0; - pr_debug("gator: gpu trace overflow\n"); - } - per_cpu(theGpuTracePos, cpu) = tracePos; - local_irq_restore(flags); -} - -#ifdef MALI_SUPPORT - -enum components { - COMPONENT_VP0 = 1, - COMPONENT_FP0 = 5, - COMPONENT_FP1, - COMPONENT_FP2, - COMPONENT_FP3, - COMPONENT_FP4, - COMPONENT_FP5, - COMPONENT_FP6, - COMPONENT_FP7, -}; - -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) & 0xF; - state = (event_id >> 24) & 0xF; - - if ((component == COMPONENT_VP0) || (component >= COMPONENT_FP0 && component <= COMPONENT_FP7)) { - if (state == ACTIVITY_START || state == ACTIVITY_STOP) { - unsigned int type = (state == ACTIVITY_START) ? GPU_START : GPU_STOP; - unsigned int unit = (component < COMPONENT_FP0) ? GPU_UNIT_VP : GPU_UNIT_FP; - unsigned int core = (component < COMPONENT_FP0) ? component - COMPONENT_VP0 : component - COMPONENT_FP0; - struct task_struct* task = (state == ACTIVITY_START) ? (struct task_struct*)d2 : NULL; - - probe_gpu_write(type, unit, core, task); - } - } -} -#endif - -GATOR_DEFINE_PROBE(gpu_activity_start, TP_PROTO(int gpu_unit, int gpu_core, struct task_struct *p)) -{ - probe_gpu_write(GPU_START, gpu_unit, gpu_core, p); -} - -GATOR_DEFINE_PROBE(gpu_activity_stop, TP_PROTO(int gpu_unit, int gpu_core)) -{ - probe_gpu_write(GPU_STOP, gpu_unit, gpu_core, NULL); -} - -int gator_trace_gpu_start(void) -{ - int cpu; - - /* - * Returns 0 for installation failed - * Absence of gpu trace points is not an error - */ - - gpu_trace_registered = mali_trace_registered = 0; - -#ifdef MALI_SUPPORT - if (!GATOR_REGISTER_TRACE(mali_timeline_event)) { - mali_trace_registered = 1; - } -#endif - - if (!mali_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 (!gpu_trace_registered && !mali_trace_registered) { - return 0; - } - - for_each_present_cpu(cpu) { - per_cpu(theGpuTraceSel, cpu) = 0; - per_cpu(theGpuTracePos, cpu) = 0; - per_cpu(theGpuTraceErr, cpu) = 0; - per_cpu(theGpuTraceBuf, cpu)[0] = kmalloc(TRACESIZE * sizeof(uint64_t), GFP_KERNEL); - per_cpu(theGpuTraceBuf, cpu)[1] = kmalloc(TRACESIZE * sizeof(uint64_t), GFP_KERNEL); - if (!per_cpu(theGpuTraceBuf, cpu)[0] || !per_cpu(theGpuTraceBuf, cpu)[1]) { -#ifdef MALI_SUPPORT - if (mali_trace_registered) { - GATOR_UNREGISTER_TRACE(mali_timeline_event); - } -#endif - if (gpu_trace_registered) { - GATOR_UNREGISTER_TRACE(gpu_activity_stop); - GATOR_UNREGISTER_TRACE(gpu_activity_start); - } - - gpu_trace_registered = mali_trace_registered = 0; - - return -1; - } - } - - return 0; -} - -int gator_trace_gpu_offline(long long **buffer) -{ - return gator_trace_gpu_read(buffer); -} - -void gator_trace_gpu_stop(void) -{ - int cpu; - - if (gpu_trace_registered || mali_trace_registered) { - for_each_present_cpu(cpu) { - kfree(per_cpu(theGpuTraceBuf, cpu)[0]); - kfree(per_cpu(theGpuTraceBuf, cpu)[1]); - per_cpu(theGpuTraceBuf, cpu)[0] = NULL; - per_cpu(theGpuTraceBuf, cpu)[1] = NULL; - } - -#ifdef MALI_SUPPORT - if (mali_trace_registered) { - GATOR_UNREGISTER_TRACE(mali_timeline_event); - } -#endif - if (gpu_trace_registered) { - GATOR_UNREGISTER_TRACE(gpu_activity_stop); - GATOR_UNREGISTER_TRACE(gpu_activity_start); - } - - gpu_trace_registered = mali_trace_registered = 0; - } -} - -int gator_trace_gpu_read(long long **buffer) -{ - int cpu = smp_processor_id(); - unsigned long flags; - uint64_t *traceBuf; - int tracePos; - - if (!per_cpu(theGpuTraceBuf, cpu)[per_cpu(theGpuTraceSel, cpu)]) - return 0; - - local_irq_save(flags); - - traceBuf = per_cpu(theGpuTraceBuf, cpu)[per_cpu(theGpuTraceSel, cpu)]; - tracePos = per_cpu(theGpuTracePos, cpu); - - per_cpu(theGpuTraceSel, cpu) = !per_cpu(theGpuTraceSel, cpu); - per_cpu(theGpuTracePos, cpu) = 0; - per_cpu(theGpuTraceErr, cpu) = 0; - - local_irq_restore(flags); - - if (buffer) - *buffer = traceBuf; - - return tracePos; -} diff --git a/drivers/gator/driver/gator_trace_gpu.h b/drivers/gator/driver/gator_trace_gpu.h deleted file mode 100644 index 894289b4316..00000000000 --- a/drivers/gator/driver/gator_trace_gpu.h +++ /dev/null @@ -1,79 +0,0 @@ -/** - * 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. - */ - -#undef TRACE_GPU -#define TRACE_GPU gpu - -#if !defined(_TRACE_GPU_H) -#define _TRACE_GPU_H - -#include - -/* - * UNIT - the GPU processor type - * 1 = Vertex Processor - * 2 = Fragment Processor - * - * CORE - the GPU processor core number - * this is not the CPU core number - */ - -/* - * Tracepoint for calling GPU unit start activity on core - */ -TRACE_EVENT(gpu_activity_start, - - TP_PROTO(int gpu_unit, int gpu_core, struct task_struct *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_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) -); - -/* - * Tracepoint for calling GPU unit stop activity on core - */ -TRACE_EVENT(gpu_activity_stop, - - TP_PROTO(int gpu_unit, int gpu_core), - - TP_ARGS(gpu_unit, 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_printk("unit=%d core=%d", - __entry->gpu_unit, __entry->gpu_core) -); - -#endif /* _TRACE_GPU_H */ - -/* This part must be outside protection */ -#include diff --git a/drivers/gator/driver/gator_trace_sched.c b/drivers/gator/driver/gator_trace_sched.c deleted file mode 100644 index dafacb75416..00000000000 --- a/drivers/gator/driver/gator_trace_sched.c +++ /dev/null @@ -1,269 +0,0 @@ -/** - * 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 -#include "gator.h" - -#define SCHED_OVERFLOW -1 -#define SCHED_SWITCH 1 -#define SCHED_PROCESS_FREE 2 - -#define SCHEDSIZE (8*1024) -#define TASK_MAP_ENTRIES 1024 /* must be power of 2 */ -#define TASK_MAX_COLLISIONS 2 - -static DEFINE_PER_CPU(uint64_t *[2], theSchedBuf); -static DEFINE_PER_CPU(int, theSchedSel); -static DEFINE_PER_CPU(int, theSchedPos); -static DEFINE_PER_CPU(int, theSchedErr); -static DEFINE_PER_CPU(uint64_t *, taskname_keys); - -enum { - STATE_CONTENTION = 0, - STATE_WAIT_ON_IO, - STATE_WAIT_ON_OTHER -}; - -int gator_trace_sched_read(long long **buffer); - -void emit_pid_name(struct task_struct* task) -{ - bool found = false; - unsigned long flags; - char taskcomm[TASK_COMM_LEN + 3]; - int 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; - - // determine if the thread name was emitted already - for (x = 0; x < TASK_MAX_COLLISIONS; x++) { - if (keys[x] == value) { - found = true; - break; - } - } - - if (!found && buffer_check_space(cpu, TIMER_BUF, TASK_COMM_LEN + 2 * MAXSIZE_PACK32 + MAXSIZE_PACK64)) { - // shift values, new value always in front - uint64_t oldv, newv = value; - for (x = 0; x < TASK_MAX_COLLISIONS; x++) { - oldv = keys[x]; - keys[x] = newv; - newv = oldv; - } - - // emit pid names, cannot use get_task_comm, as it's not exported on all kernel versions - if (strlcpy(taskcomm, task->comm, TASK_COMM_LEN) == TASK_COMM_LEN - 1) - // append ellipses if task->comm has length of TASK_COMM_LEN - 1 - strcat(taskcomm, "..."); - - // disable interrupts to synchronize with hrtimer populating timer buf - local_irq_save(flags); - gator_buffer_write_packed_int(cpu, TIMER_BUF, MESSAGE_PID_NAME); - gator_buffer_write_packed_int64(cpu, TIMER_BUF, gator_get_time()); - gator_buffer_write_packed_int(cpu, TIMER_BUF, task->pid); - gator_buffer_write_string(cpu, TIMER_BUF, taskcomm); - local_irq_restore(flags); - } -} - -static void probe_sched_write(int type, struct task_struct* task, struct task_struct* old_task) -{ - int schedPos, cookie = 0, state = 0; - unsigned long flags; - uint64_t *schedBuf, time; - int cpu = smp_processor_id(); - int pid = task->pid; - int tgid = task->tgid; - - if (!per_cpu(theSchedBuf, cpu)[per_cpu(theSchedSel, cpu)]) - return; - - if (type == SCHED_SWITCH) { - // do as much work as possible before disabling interrupts - cookie = get_exec_cookie(cpu, TIMER_BUF, task); - emit_pid_name(task); - if (old_task->state == 0) - state = STATE_CONTENTION; - else if (old_task->in_iowait) - state = STATE_WAIT_ON_IO; - else - state = STATE_WAIT_ON_OTHER; - } - - // disable interrupts to synchronize with gator_trace_sched_read(); spinlocks not needed since percpu buffers are used - local_irq_save(flags); - - time = gator_get_time(); - schedPos = per_cpu(theSchedPos, cpu); - schedBuf = per_cpu(theSchedBuf, cpu)[per_cpu(theSchedSel, cpu)]; - - if (schedPos < (SCHEDSIZE - 100)) { - // capture - schedBuf[schedPos++] = type; - schedBuf[schedPos++] = time; - schedBuf[schedPos++] = pid; - schedBuf[schedPos++] = tgid; - schedBuf[schedPos++] = cookie; - schedBuf[schedPos++] = state; - } else if (!per_cpu(theSchedErr, cpu)) { - per_cpu(theSchedErr, cpu) = 1; - schedBuf[schedPos++] = SCHED_OVERFLOW; - schedBuf[schedPos++] = time; - schedBuf[schedPos++] = 0; - schedBuf[schedPos++] = 0; - schedBuf[schedPos++] = 0; - schedBuf[schedPos++] = 0; - pr_debug("gator: tracepoint overflow\n"); - } - per_cpu(theSchedPos, cpu) = schedPos; - local_irq_restore(flags); -} - -// special case used during a suspend of the system -static void trace_sched_insert_idle(void) -{ - unsigned long flags; - uint64_t *schedBuf; - int schedPos, cpu = smp_processor_id(); - - if (!per_cpu(theSchedBuf, cpu)[per_cpu(theSchedSel, cpu)]) - return; - - local_irq_save(flags); - - schedPos = per_cpu(theSchedPos, cpu); - schedBuf = per_cpu(theSchedBuf, cpu)[per_cpu(theSchedSel, cpu)]; - - if (schedPos < (SCHEDSIZE - (6 * 8))) { - // capture - schedBuf[schedPos++] = SCHED_SWITCH; - schedBuf[schedPos++] = gator_get_time(); - schedBuf[schedPos++] = 0; // idle pid is zero - schedBuf[schedPos++] = 0; // idle tid is zero - schedBuf[schedPos++] = 0; // idle cookie is zero - schedBuf[schedPos++] = STATE_WAIT_ON_OTHER; - } - - per_cpu(theSchedPos, cpu) = schedPos; - local_irq_restore(flags); -} - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) -GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct rq *rq, struct task_struct *prev, struct task_struct *next)) -#else -GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct task_struct *prev, struct task_struct *next)) -#endif -{ - probe_sched_write(SCHED_SWITCH, next, prev); -} - -GATOR_DEFINE_PROBE(sched_process_free, TP_PROTO(struct task_struct *p)) -{ - probe_sched_write(SCHED_PROCESS_FREE, p, 0); -} - -static int register_scheduler_tracepoints(void) { - // register tracepoints - if (GATOR_REGISTER_TRACE(sched_switch)) - goto fail_sched_switch; - if (GATOR_REGISTER_TRACE(sched_process_free)) - goto fail_sched_process_free; - pr_debug("gator: registered tracepoints\n"); - - return 0; - - // unregister tracepoints on error -fail_sched_process_free: - GATOR_UNREGISTER_TRACE(sched_switch); -fail_sched_switch: - pr_err("gator: tracepoints failed to activate, please verify that tracepoints are enabled in the linux kernel\n"); - - return -1; -} - -int gator_trace_sched_start(void) -{ - int cpu, size; - - for_each_present_cpu(cpu) { - per_cpu(theSchedSel, cpu) = 0; - per_cpu(theSchedPos, cpu) = 0; - per_cpu(theSchedErr, cpu) = 0; - per_cpu(theSchedBuf, cpu)[0] = kmalloc(SCHEDSIZE * sizeof(uint64_t), GFP_KERNEL); - per_cpu(theSchedBuf, cpu)[1] = kmalloc(SCHEDSIZE * sizeof(uint64_t), GFP_KERNEL); - if (!per_cpu(theSchedBuf, cpu)) - return -1; - - size = TASK_MAP_ENTRIES * TASK_MAX_COLLISIONS * sizeof(uint64_t); - 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); - } - - return register_scheduler_tracepoints(); -} - -int gator_trace_sched_offline(long long **buffer) -{ - trace_sched_insert_idle(); - return gator_trace_sched_read(buffer); -} - -static void unregister_scheduler_tracepoints(void) -{ - GATOR_UNREGISTER_TRACE(sched_switch); - GATOR_UNREGISTER_TRACE(sched_process_free); - pr_debug("gator: unregistered tracepoints\n"); -} - -void gator_trace_sched_stop(void) -{ - int cpu; - unregister_scheduler_tracepoints(); - - for_each_present_cpu(cpu) { - kfree(per_cpu(theSchedBuf, cpu)[0]); - kfree(per_cpu(theSchedBuf, cpu)[1]); - per_cpu(theSchedBuf, cpu)[0] = NULL; - per_cpu(theSchedBuf, cpu)[1] = NULL; - kfree(per_cpu(taskname_keys, cpu)); - } -} - -int gator_trace_sched_read(long long **buffer) -{ - int cpu = smp_processor_id(); - unsigned long flags; - uint64_t *schedBuf; - int schedPos; - - if (!per_cpu(theSchedBuf, cpu)[per_cpu(theSchedSel, cpu)]) - return 0; - - local_irq_save(flags); - - schedBuf = per_cpu(theSchedBuf, cpu)[per_cpu(theSchedSel, cpu)]; - schedPos = per_cpu(theSchedPos, cpu); - - per_cpu(theSchedSel, cpu) = !per_cpu(theSchedSel, cpu); - per_cpu(theSchedPos, cpu) = 0; - per_cpu(theSchedErr, cpu) = 0; - - local_irq_restore(flags); - - if (buffer) - *buffer = schedBuf; - - return schedPos; -} -- cgit v1.2.3