Initial snapshot of stm-log
Preliminary changes for the stm-log userspace library for
logging via STM.
Change-Id: Ief82b6c8c7847b26ebbbe0d9f6512c7d97cd48f5
diff --git a/stm-log.c b/stm-log.c
new file mode 100644
index 0000000..90e93ea
--- /dev/null
+++ b/stm-log.c
@@ -0,0 +1,183 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <linux/coresight-stm.h>
+#include <stm-log.h>
+#include <string.h>
+
+#ifdef DEBUG
+#define LOG_TAG "STM-LOG"
+#include <cutils/log.h>
+#endif
+
+#define STM_LOG_DEV "/dev/coresight-stm"
+#define STM_LOG_MAGIC_0 0xf0
+#define STM_LOG_MAGIC_1 0xf1
+
+static uint8_t dflt_stm_entity_id = OST_ENTITY_NONE;
+static uint8_t dflt_stm_proto_id = 0;
+static uint32_t dflt_stm_options = STM_OPTION_TIMESTAMPED;
+
+typedef struct
+{
+ uint8_t magic[2];
+ uint8_t entity;
+ uint8_t proto;
+ uint32_t options;
+} stmlog_t;
+
+void stm_log_initdefaults(uint32_t init_mask,
+ uint8_t entity_id,
+ uint8_t proto_id,
+ uint32_t options)
+{
+ if ((init_mask & STM_DFLT_ENTITY) != 0) {
+ dflt_stm_entity_id = entity_id;
+ }
+ if ((init_mask & STM_DFLT_PROTOCOL) != 0) {
+ dflt_stm_proto_id = proto_id;
+ }
+ if ((init_mask & STM_DFLT_OPTIONS) != 0) {
+ dflt_stm_options = options;
+ }
+#ifdef DEBUG
+ if ((init_mask & ~(STM_DFLT_ENTITY
+ | STM_DFLT_PROTOCOL
+ | STM_DFLT_OPTIONS)) != 0) {
+ ALOGE("Invalid init mask 0x%08x", init_mask);
+ }
+#endif
+}
+
+int STMLOG_WRITE(int len, void *data) {
+ int fd;
+ int rc = -1;
+ fd = open(STM_LOG_DEV, O_WRONLY);
+ if (fd >= 0) {
+ do {
+ rc = write(fd, data, len);
+ if (rc == -1)
+ break;
+ len -= rc;
+ } while (len > 0);
+ close(fd);
+ }
+#ifdef DEBUG
+ ALOGE("Failed to write to stm log");
+#endif
+ return rc;
+}
+
+void stm_log(const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ stm_log_ex(dflt_stm_entity_id,
+ dflt_stm_proto_id,
+ dflt_stm_options,
+ format,
+ ap);
+ va_end(ap);
+}
+
+void stm_logbin(int length, void *data)
+{
+ stm_logbin_ex(dflt_stm_entity_id,
+ dflt_stm_proto_id,
+ dflt_stm_options,
+ length,
+ data);
+}
+
+void stm_log_ex(uint8_t entity_id,
+ uint8_t proto_id,
+ uint32_t options,
+ const char *format, ...)
+{
+ int length;
+ char *buf;
+ stmlog_t *log;
+ va_list ap;
+
+ va_start(ap, format);
+ length = vsnprintf(NULL, 0, format, ap);
+ if (length >= 0) {
+ length++;
+ buf = (char *)malloc(sizeof(stmlog_t) + length);
+ if (buf) {
+ log = (stmlog_t *)buf;
+ log->magic[0] = STM_LOG_MAGIC_0;
+ log->magic[1] = STM_LOG_MAGIC_1;
+ log->entity = entity_id;
+ log->proto = proto_id;
+ log->options = options;
+ vsnprintf(buf + sizeof(stmlog_t), length, format, ap);
+ STMLOG_WRITE(sizeof(stmlog_t) + length, buf);
+ free(buf);
+ }
+#ifdef DEBUG
+ else {
+ ALOGE("Out of memory allocating temp buffer");
+ }
+#endif
+ }
+ va_end(ap);
+}
+
+void stm_logbin_ex(uint8_t entity_id,
+ uint8_t proto_id,
+ uint32_t options,
+ int length,
+ void *data)
+{
+ uint8_t *buf;
+ stmlog_t *stm;
+ buf = (uint8_t *)malloc(sizeof(stmlog_t) + length);
+ if (buf) {
+ stm = (stmlog_t *)buf;
+ stm->magic[0] = STM_LOG_MAGIC_0;
+ stm->magic[1] = STM_LOG_MAGIC_1;
+ stm->entity = entity_id;
+ stm->proto = proto_id;
+ stm->options = options;
+ memcpy(buf + sizeof(stmlog_t), data, length);
+ STMLOG_WRITE(sizeof(stmlog_t) + length, buf);
+ free(buf);
+ }
+#ifdef DEBUG
+ else {
+ ALOGE("Out of memory allocating temp buffer");
+ }
+#endif
+}