Skip to content

Commit 33c45a0

Browse files
committed
Allow turning uart/screen logs off
1 parent 4885f6f commit 33c45a0

File tree

1 file changed

+82
-5
lines changed
  • src/kernel/support

1 file changed

+82
-5
lines changed

src/kernel/support/io.c

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,80 @@ static lock stdout_lock;
5151

5252
extern char preemption_over;
5353

54+
#define STDIO_LOG_UART (1 << 0)
55+
#define STDIO_LOG_SCREEN (1 << 1)
56+
#define STDIO_LOG_MAX (STDIO_LOG_UART | STDIO_LOG_SCREEN)
57+
static uint8_t stdio_flags[3] =
58+
{
59+
[1] = STDIO_LOG_MAX,
60+
[2] = STDIO_LOG_MAX,
61+
};
62+
63+
static void log_cmd(const char *cmd, char *args)
64+
{
65+
uint8_t files = 0b110;
66+
uint8_t mask = STDIO_LOG_MAX;
67+
bool on;
68+
char *parts[3] = {};
69+
70+
while(*args == ' ') ++args;
71+
for(size_t i = 0; i < 3; ++i)
72+
{
73+
char *delim = strchr(args, ' ');
74+
parts[i] = args;
75+
if(!delim)
76+
{
77+
goto skip;
78+
}
79+
*delim = '\0';
80+
args = delim + 1;
81+
while(*args == ' ') ++args;
82+
}
83+
if(*args != '\0')
84+
{
85+
iprintf("Too many arguments\n");
86+
goto help;
87+
}
88+
skip:;
89+
if(parts[0][0] == '\0')
90+
{
91+
goto help;
92+
}
93+
94+
size_t idx = 0;
95+
if( strcmp(parts[idx], "stdout") == 0) { files = (1 << 1); ++idx; }
96+
else if(strcmp(parts[idx], "stderr") == 0) { files = (1 << 2); ++idx; }
97+
98+
if(!parts[idx]) { iprintf("Too few arguments\n"); goto help; }
99+
if( strcmp(parts[idx], "uart") == 0) { mask = STDIO_LOG_UART; ++idx; }
100+
else if(strcmp(parts[idx], "screen") == 0) { mask = STDIO_LOG_SCREEN; ++idx; }
101+
102+
if(!parts[idx]) { iprintf("Too few arguments\n"); goto help; }
103+
if( strcmp(parts[idx], "on") == 0) { on = true; ++idx; }
104+
else if(strcmp(parts[idx], "off") == 0) { on = false; ++idx; }
105+
else { iprintf("Bad arguments\n"); goto help; }
106+
107+
for(uint8_t f = 0; f < 3; ++f)
108+
{
109+
if(files & (1 << f))
110+
{
111+
stdio_flags[f] = on ? (stdio_flags[f] | mask) : (stdio_flags[f] & ~mask);
112+
}
113+
}
114+
115+
return;
116+
help:;
117+
iprintf("Usage: log [stdout|stderr] [uart|screen] on|off\n");
118+
}
119+
54120
void io_init(void)
55121
{
56122
// Grab a page and map it three times, ringbuffer style
57123
uint64_t stdout_buf = ppage_alloc();
58124
map_range(STDOUT_BASE + (0 * STDOUT_BUFLEN), stdout_buf, STDOUT_BUFLEN, 3, 1, true);
59125
map_range(STDOUT_BASE + (1 * STDOUT_BUFLEN), stdout_buf, STDOUT_BUFLEN, 3, 1, true);
60126
map_range(STDOUT_BASE + (2 * STDOUT_BUFLEN), stdout_buf, STDOUT_BUFLEN, 3, 1, true);
127+
command_register("log", "control stdio logging", log_cmd);
61128
}
62129

63130
void set_stdout_blocking(bool block)
@@ -91,14 +158,24 @@ ssize_t _write_r(struct _reent *reent, int file, const void *ptr, size_t len)
91158
default: panic("Write to unknown fd: %d", file);
92159
}
93160
const char *str = ptr;
94-
for(size_t i = 0; i < len; ++i)
161+
uint8_t flags = stdio_flags[file];
162+
if(flags & STDIO_LOG_MAX)
95163
{
96-
if(str[i] == '\0')
164+
for(size_t i = 0; i < len; ++i)
97165
{
98-
serial_putc('\r');
166+
if(flags & STDIO_LOG_UART)
167+
{
168+
if(str[i] == '\0')
169+
{
170+
serial_putc('\r');
171+
}
172+
serial_putc(str[i]);
173+
}
174+
if(flags & STDIO_LOG_SCREEN)
175+
{
176+
screen_putc(str[i]);
177+
}
99178
}
100-
serial_putc(str[i]);
101-
screen_putc(str[i]);
102179
}
103180
if(file == 1)
104181
{

0 commit comments

Comments
 (0)