2024-11-02 11:31:51 +00:00
|
|
|
#include <mango/printk.h>
|
|
|
|
|
#include <mango/locks.h>
|
|
|
|
|
#include <mango/console.h>
|
|
|
|
|
#include <mango/libc/stdio.h>
|
2023-02-04 19:03:45 +00:00
|
|
|
#include <stdarg.h>
|
2023-02-03 20:26:02 +00:00
|
|
|
|
|
|
|
|
#define LOG_BUFFER_SIZE 0x40000
|
2023-02-04 19:03:45 +00:00
|
|
|
#define LOG_MSG_SIZE 0x100
|
|
|
|
|
|
2023-04-12 20:17:11 +01:00
|
|
|
static struct console *early_console = NULL;
|
2023-02-04 19:03:45 +00:00
|
|
|
|
|
|
|
|
static spin_lock_t log_buffer_lock = SPIN_LOCK_INIT;
|
2023-02-03 20:26:02 +00:00
|
|
|
|
|
|
|
|
static char log_buffer[LOG_BUFFER_SIZE] = {0};
|
2023-02-04 19:03:45 +00:00
|
|
|
/* index of the last character in log_buffer that has been written
|
|
|
|
|
to the console */
|
|
|
|
|
static unsigned int log_buffer_readp = 0;
|
|
|
|
|
/* index of the last character in log_buffer that has been logged
|
|
|
|
|
(but not necessarily written to the console) */
|
|
|
|
|
static unsigned int log_buffer_writep = 0;
|
|
|
|
|
|
|
|
|
|
static void flush_log_buffer(void)
|
|
|
|
|
{
|
2023-05-06 21:32:19 +01:00
|
|
|
/*
|
2023-02-04 19:03:45 +00:00
|
|
|
if (!early_console) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-05-06 21:32:19 +01:00
|
|
|
|
2023-02-04 19:03:45 +00:00
|
|
|
console_write(early_console, log_buffer + log_buffer_readp, log_buffer_writep - log_buffer_readp);
|
2023-05-06 21:32:19 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
unsigned long flags;
|
|
|
|
|
struct queue *consoles = get_consoles(&flags);
|
|
|
|
|
queue_foreach(struct console, con, consoles, c_list) {
|
|
|
|
|
console_write(con, log_buffer + log_buffer_readp, log_buffer_writep - log_buffer_readp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
put_consoles(consoles, flags);
|
2023-02-04 19:03:45 +00:00
|
|
|
log_buffer_readp = log_buffer_writep;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void save_log_message(const char *msg)
|
|
|
|
|
{
|
|
|
|
|
unsigned int i = 0;
|
|
|
|
|
while (1) {
|
|
|
|
|
if (log_buffer_writep == LOG_BUFFER_SIZE - 1) {
|
|
|
|
|
log_buffer[log_buffer_writep] = '\0';
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (msg[i] == '\0') {
|
|
|
|
|
break;
|
|
|
|
|
}
|
2023-05-06 21:32:19 +01:00
|
|
|
|
2023-02-04 19:03:45 +00:00
|
|
|
log_buffer[log_buffer_writep++] = msg[i++];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-12 20:17:11 +01:00
|
|
|
void early_printk_init(struct console *con)
|
2023-02-04 19:03:45 +00:00
|
|
|
{
|
|
|
|
|
early_console = con;
|
|
|
|
|
}
|
2023-02-03 20:26:02 +00:00
|
|
|
|
|
|
|
|
int printk(const char *format, ...)
|
|
|
|
|
{
|
2023-02-04 19:03:45 +00:00
|
|
|
char msg[LOG_MSG_SIZE];
|
|
|
|
|
|
|
|
|
|
va_list arg;
|
|
|
|
|
va_start(arg, format);
|
|
|
|
|
int len = vsnprintf(msg, sizeof msg - 1, format, arg);
|
|
|
|
|
va_end(arg);
|
|
|
|
|
|
|
|
|
|
msg[len] = '\n';
|
|
|
|
|
msg[len + 1] = '\0';
|
|
|
|
|
|
2023-02-08 17:10:13 +00:00
|
|
|
if (log_buffer_writep == LOG_BUFFER_SIZE - 1) {
|
|
|
|
|
console_write(early_console, msg, len + 1);
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-04 19:03:45 +00:00
|
|
|
unsigned long flags;
|
|
|
|
|
spin_lock_irqsave(&log_buffer_lock, &flags);
|
|
|
|
|
save_log_message(msg);
|
|
|
|
|
spin_unlock_irqrestore(&log_buffer_lock, flags);
|
|
|
|
|
|
|
|
|
|
flush_log_buffer();
|
2023-05-06 21:32:19 +01:00
|
|
|
|
2023-02-04 19:03:45 +00:00
|
|
|
return 0;
|
2023-02-03 20:26:02 +00:00
|
|
|
}
|