Skip to content

Commit 2c8fb0a

Browse files
committed
MTPRINTF
1 parent bb28b2d commit 2c8fb0a

2 files changed

Lines changed: 197 additions & 0 deletions

File tree

src/include/mtprintf.h

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
#ifndef ___MTPRINTF
2+
#define ___MTPRINTF
3+
4+
/*
5+
* Copyright (c) 2020 Intel Corporation
6+
*
7+
* SPDX-License-Identifier: Apache-2.0
8+
*/
9+
#include <stdarg.h>
10+
#include <stdbool.h>
11+
#include <stddef.h>
12+
13+
#include <xtensa/hal.h>
14+
15+
/* (Cribbed from Zephyr: arch/x86/zefi/printf.h) */
16+
17+
/* Tiny, but not-as-primitive-as-it-looks implementation of something
18+
* like s/n/printf(). Handles %d, %x, %p, %c and %s only, allows a
19+
* "l" qualifier on %d and %x (and silently ignores one %s/%c/%p).
20+
* Accepts, but ignores, field width and precision values that match:
21+
* the regex: [0-9]*\.?[0-9]*
22+
*/
23+
24+
/* Use this 1M region for the log data (see notes in mt8195-load.py).
25+
* Remember that the firmware loader doesn't (!!!) zero this RAM, and
26+
* that it starts out populated with seeming garbage from firmware
27+
* startup (there are some bootloader-looking strings in there). So
28+
* something very early on needs to set MTPRINTF_LEN=0.
29+
*
30+
* Obviously this will cause overruns the second log data enters the
31+
* last four bytes. It's a debug tool. NOT RELIABLE FOR PRODUCTION
32+
* USE.
33+
*/
34+
#define MTPRINTF_BUF ((char *)0x60700000)
35+
#define MTPRINTF_LEN (*(int*)0x607ffffc)
36+
37+
static inline void z_putchar(char c)
38+
{
39+
MTPRINTF_BUF[MTPRINTF_LEN++] = c;
40+
MTPRINTF_BUF[MTPRINTF_LEN] = 0;
41+
}
42+
43+
struct _pfr {
44+
char *buf;
45+
int len;
46+
int idx;
47+
};
48+
49+
static void pc(struct _pfr *r, int c)
50+
{
51+
if (r->buf != NULL) {
52+
if (r->idx <= r->len) {
53+
r->buf[r->idx] = c;
54+
}
55+
} else {
56+
z_putchar(c);
57+
}
58+
r->idx++;
59+
}
60+
61+
static void prdec(struct _pfr *r, long v)
62+
{
63+
if (v < 0) {
64+
pc(r, '-');
65+
v = -v;
66+
}
67+
68+
char digs[11 * sizeof(long)/4];
69+
int i = sizeof(digs) - 1;
70+
71+
digs[i--] = 0;
72+
while (v || i == 9) {
73+
digs[i--] = '0' + (v % 10);
74+
v /= 10;
75+
}
76+
77+
while (digs[++i] != '\0') {
78+
pc(r, digs[i]);
79+
}
80+
}
81+
82+
static void endrec(struct _pfr *r)
83+
{
84+
if (r->buf && r->idx < r->len) {
85+
r->buf[r->idx] = 0;
86+
}
87+
}
88+
89+
static int vpf(struct _pfr *r, const char *f, va_list ap)
90+
{
91+
for (/**/; *f != '\0'; f++) {
92+
bool islong = false;
93+
94+
if (*f != '%') {
95+
pc(r, *f);
96+
continue;
97+
}
98+
99+
if (f[1] == 'l') {
100+
islong = sizeof(long) > 4;
101+
f++;
102+
}
103+
104+
/* Ignore (but accept) field width and precision values */
105+
while (f[1] >= '0' && f[1] <= '9') {
106+
f++;
107+
}
108+
if (f[1] == '.') {
109+
f++;
110+
}
111+
while (f[1] >= '0' && f[1] <= '9') {
112+
f++;
113+
}
114+
115+
switch (*(++f)) {
116+
case 0:
117+
return r->idx;
118+
case '%':
119+
pc(r, '%');
120+
break;
121+
case 'c':
122+
pc(r, va_arg(ap, int));
123+
break;
124+
case 's': {
125+
char *s = va_arg(ap, char *);
126+
127+
while (*s != '\0')
128+
pc(r, *s++);
129+
break;
130+
}
131+
case 'p':
132+
pc(r, '0');
133+
pc(r, 'x'); /* fall through... */
134+
islong = sizeof(long) > 4;
135+
case 'x': {
136+
int i, sig = 0;
137+
unsigned long v = islong ? va_arg(ap, unsigned long)
138+
: va_arg(ap, unsigned int);
139+
for (i = 2*sizeof(long) - 1; i >= 0; i--) {
140+
int d = (v >> (i*4)) & 0xf;
141+
142+
sig += !!d;
143+
if (sig || i == 0)
144+
pc(r, "0123456789abcdef"[d]);
145+
}
146+
break;
147+
}
148+
case 'd':
149+
prdec(r, va_arg(ap, int));
150+
break;
151+
default:
152+
pc(r, '%');
153+
pc(r, *f);
154+
}
155+
}
156+
endrec(r);
157+
return r->idx;
158+
}
159+
160+
#define CALL_VPF(rec) \
161+
va_list ap; \
162+
va_start(ap, f); \
163+
ret = vpf(&r, f, ap); \
164+
va_end(ap);
165+
166+
static inline int mtsnprintf(char *buf, unsigned long len, const char *f, ...)
167+
{
168+
int ret = 0;
169+
struct _pfr r = { .buf = buf, .len = len };
170+
171+
CALL_VPF(&r);
172+
return ret;
173+
}
174+
175+
static inline int mtsprintf(char *buf, const char *f, ...)
176+
{
177+
int ret = 0;
178+
struct _pfr r = { .buf = buf, .len = 0x7fffffff };
179+
180+
CALL_VPF(&r);
181+
return ret;
182+
}
183+
184+
static inline int mtprintf(const char *f, ...)
185+
{
186+
int ret = 0;
187+
struct _pfr r = {0};
188+
189+
CALL_VPF(&r);
190+
xthal_dcache_region_writeback(MTPRINTF_BUF, 0x10000);
191+
return ret;
192+
}
193+
194+
#endif // ndef ___MTPRINTF

src/init/init.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <version.h>
4444
#endif
4545
#include <sof/lib/ams.h>
46+
#include <mtprintf.h> //DEBUG
4647

4748
LOG_MODULE_REGISTER(init, CONFIG_SOF_LOG_LEVEL);
4849

@@ -334,7 +335,9 @@ static int primary_core_init(int argc, char *argv[], struct sof *sof)
334335
#ifndef __ZEPHYR__
335336
int main(int argc, char *argv[])
336337
{
338+
MTPRINTF_LEN = 0;
337339
int err = 0;
340+
mtprintf("Hello SOF World!\n");
338341

339342
trace_point(TRACE_BOOT_START);
340343

0 commit comments

Comments
 (0)