First version
[3rdparty/ote_partner/tlk.git] / lib / debug / debug.c
1 /*
2  * Copyright (c) 2008-2012 Travis Geiselbrecht
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23
24 #include <ctype.h>
25 #include <debug.h>
26 #include <stdlib.h>
27 #include <printf.h>
28 #include <list.h>
29 #include <string.h>
30 #include <arch/ops.h>
31 #include <platform.h>
32 #include <platform/debug.h>
33 #include <kernel/thread.h>
34
35 /* Physical address of cbuf */
36 unsigned long cbuf_addr;
37 unsigned long cbstruct_addr;
38
39 unsigned int ote_logger_enabled = 1;
40
41 /* Internal TLK buffer used to store TLK prints before we get
42  * a shared buffer from linux.
43  * At one point, we'll push all this to the shared buffer.
44  */
45 char early_logbuf[EARLYBUF_SIZE];
46
47 /* Char count for early prints */
48 int early_char_count;
49
50 void spin(uint32_t usecs)
51 {
52         lk_bigtime_t start = current_time_hires();
53
54         while ((current_time_hires() - start) < usecs)
55                 ;
56 }
57
58 void halt(void)
59 {
60         enter_critical_section(); // disable ints
61         platform_halt();
62 }
63
64 void _panic(void *caller, const char *fmt, ...)
65 {
66         ote_logger_enabled = 0;
67
68         dprintf(ALWAYS, "panic (caller %p): ", caller);
69
70         va_list ap;
71         va_start(ap, fmt);
72         _dvprintf(fmt, ap);
73         va_end(ap);
74
75         halt();
76 }
77
78 #if !DISABLE_DEBUG_OUTPUT
79
80 int _dputs(const char *str)
81 {
82         while(*str != 0) {
83                 _dputc(*str++);
84         }
85
86         return 0;
87 }
88
89 static void cbuf_write(char c)
90 {
91         struct circular_buffer *cb = (struct circular_buffer *)cbstruct_addr;
92         char *cbuf = (char*)cbuf_addr;
93
94         cbuf[cb->end] = c;
95         cb->end = (cb->end + 1) % cb->size;
96
97         if (cb->end == cb->start) {
98                 cb->overflow = 1;
99                 cb->start = (cb->start + 1) % cb->size;
100         }
101 }
102
103 static int _dprintf_output_func(char c, void *state)
104 {
105         /* in case we dont get the shared memory buffer from the NS world */
106         if (!ote_logger_enabled) {
107                 _dputc(c);
108                 goto out;
109         }
110
111         /* If physical address has not been initialized, means we have
112          * not yet received shared buffer from linux.
113          * Buffer logs in TLK internal buffer for now.
114          */
115         if (cbstruct_addr == 0) {
116
117                 if (c == '\0')
118                         return INT_MAX;
119
120                 *(char *)(early_logbuf + early_char_count) = c;
121                 *(char *)(early_logbuf + early_char_count + 1) = '\0';
122                 early_char_count++;
123                 if (early_char_count > (EARLYBUF_SIZE - 2)) {
124                         _dputs("\nTLK early buffer overflow, \
125                                 overwriting data!\n");
126                         early_char_count = 0;
127                 }
128         } else {
129
130                 /* We have received shared buffer. Write to it's physical address */
131                 if (c == '\0')
132                         return INT_MAX;
133
134                 cbuf_write(c);
135         }
136
137 out:
138         return INT_MAX;
139 }
140
141 int _dprintf(const char *fmt, ...)
142 {
143         int err;
144
145         va_list ap;
146         va_start(ap, fmt);
147         err = _printf_engine(&_dprintf_output_func, NULL, fmt, ap);
148         va_end(ap);
149
150         return err;
151 }
152
153 int _dvprintf(const char *fmt, va_list ap)
154 {
155         int err;
156
157         err = _printf_engine(&_dprintf_output_func, NULL, fmt, ap);
158
159         return err;
160 }
161
162 void hexdump(const void *ptr, size_t len)
163 {
164         addr_t address = (addr_t)ptr;
165         size_t count;
166         int i;
167
168         for (count = 0 ; count < len; count += 16) {
169                 printf("0x%08lx: ", address);
170                 printf("%08x %08x %08x %08x |", *(const uint32_t *)address, *(const uint32_t *)(address + 4), *(const uint32_t *)(address + 8), *(const uint32_t *)(address + 12));
171                 for (i=0; i < 16; i++) {
172                         char c = *(const char *)(address + i);
173                         if (isalpha(c)) {
174                                 printf("%c", c);
175                         } else {
176                                 printf(".");
177                         }
178                 }
179                 printf("|\n");
180                 address += 16;
181         }
182 }
183
184 void hexdump8(const void *ptr, size_t len)
185 {
186         addr_t address = (addr_t)ptr;
187         size_t count;
188         int i;
189
190         for (count = 0 ; count < len; count += 16) {
191                 printf("0x%08lx: ", address);
192                 for (i=0; i < 16; i++) {
193                         printf("0x%02hhx ", *(const uint8_t *)(address + i));
194                 }
195                 printf("\n");
196                 address += 16;
197         }
198 }
199
200 #endif // !DISABLE_DEBUG_OUTPUT
201