blob: 90e93ea4001aca6d944614403bc76847c7347611 [file] [log] [blame]
David Ngcac0b622012-10-18 19:13:49 -07001/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <stdint.h>
30#include <stdarg.h>
31#include <stdio.h>
32#include <sys/types.h>
33#include <sys/stat.h>
34#include <fcntl.h>
35#include <linux/coresight-stm.h>
36#include <stm-log.h>
37#include <string.h>
38
39#ifdef DEBUG
40#define LOG_TAG "STM-LOG"
41#include <cutils/log.h>
42#endif
43
44#define STM_LOG_DEV "/dev/coresight-stm"
45#define STM_LOG_MAGIC_0 0xf0
46#define STM_LOG_MAGIC_1 0xf1
47
48static uint8_t dflt_stm_entity_id = OST_ENTITY_NONE;
49static uint8_t dflt_stm_proto_id = 0;
50static uint32_t dflt_stm_options = STM_OPTION_TIMESTAMPED;
51
52typedef struct
53{
54 uint8_t magic[2];
55 uint8_t entity;
56 uint8_t proto;
57 uint32_t options;
58} stmlog_t;
59
60void stm_log_initdefaults(uint32_t init_mask,
61 uint8_t entity_id,
62 uint8_t proto_id,
63 uint32_t options)
64{
65 if ((init_mask & STM_DFLT_ENTITY) != 0) {
66 dflt_stm_entity_id = entity_id;
67 }
68 if ((init_mask & STM_DFLT_PROTOCOL) != 0) {
69 dflt_stm_proto_id = proto_id;
70 }
71 if ((init_mask & STM_DFLT_OPTIONS) != 0) {
72 dflt_stm_options = options;
73 }
74#ifdef DEBUG
75 if ((init_mask & ~(STM_DFLT_ENTITY
76 | STM_DFLT_PROTOCOL
77 | STM_DFLT_OPTIONS)) != 0) {
78 ALOGE("Invalid init mask 0x%08x", init_mask);
79 }
80#endif
81}
82
83int STMLOG_WRITE(int len, void *data) {
84 int fd;
85 int rc = -1;
86 fd = open(STM_LOG_DEV, O_WRONLY);
87 if (fd >= 0) {
88 do {
89 rc = write(fd, data, len);
90 if (rc == -1)
91 break;
92 len -= rc;
93 } while (len > 0);
94 close(fd);
95 }
96#ifdef DEBUG
97 ALOGE("Failed to write to stm log");
98#endif
99 return rc;
100}
101
102void stm_log(const char *format, ...)
103{
104 va_list ap;
105 va_start(ap, format);
106 stm_log_ex(dflt_stm_entity_id,
107 dflt_stm_proto_id,
108 dflt_stm_options,
109 format,
110 ap);
111 va_end(ap);
112}
113
114void stm_logbin(int length, void *data)
115{
116 stm_logbin_ex(dflt_stm_entity_id,
117 dflt_stm_proto_id,
118 dflt_stm_options,
119 length,
120 data);
121}
122
123void stm_log_ex(uint8_t entity_id,
124 uint8_t proto_id,
125 uint32_t options,
126 const char *format, ...)
127{
128 int length;
129 char *buf;
130 stmlog_t *log;
131 va_list ap;
132
133 va_start(ap, format);
134 length = vsnprintf(NULL, 0, format, ap);
135 if (length >= 0) {
136 length++;
137 buf = (char *)malloc(sizeof(stmlog_t) + length);
138 if (buf) {
139 log = (stmlog_t *)buf;
140 log->magic[0] = STM_LOG_MAGIC_0;
141 log->magic[1] = STM_LOG_MAGIC_1;
142 log->entity = entity_id;
143 log->proto = proto_id;
144 log->options = options;
145 vsnprintf(buf + sizeof(stmlog_t), length, format, ap);
146 STMLOG_WRITE(sizeof(stmlog_t) + length, buf);
147 free(buf);
148 }
149#ifdef DEBUG
150 else {
151 ALOGE("Out of memory allocating temp buffer");
152 }
153#endif
154 }
155 va_end(ap);
156}
157
158void stm_logbin_ex(uint8_t entity_id,
159 uint8_t proto_id,
160 uint32_t options,
161 int length,
162 void *data)
163{
164 uint8_t *buf;
165 stmlog_t *stm;
166 buf = (uint8_t *)malloc(sizeof(stmlog_t) + length);
167 if (buf) {
168 stm = (stmlog_t *)buf;
169 stm->magic[0] = STM_LOG_MAGIC_0;
170 stm->magic[1] = STM_LOG_MAGIC_1;
171 stm->entity = entity_id;
172 stm->proto = proto_id;
173 stm->options = options;
174 memcpy(buf + sizeof(stmlog_t), data, length);
175 STMLOG_WRITE(sizeof(stmlog_t) + length, buf);
176 free(buf);
177 }
178#ifdef DEBUG
179 else {
180 ALOGE("Out of memory allocating temp buffer");
181 }
182#endif
183}