@@ -51,13 +51,80 @@ static lock stdout_lock;
5151
5252extern 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+
54120void 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
63130void 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