kernel: add basic console registration system and printk()
This commit is contained in:
@@ -1,12 +1,52 @@
|
||||
#include <socks/console.h>
|
||||
#include <socks/machine/console.h>
|
||||
#include <socks/queue.h>
|
||||
#include <socks/locks.h>
|
||||
#include <socks/libc/string.h>
|
||||
|
||||
void console_init(void)
|
||||
static queue_t consoles;
|
||||
static spin_lock_t consoles_lock = SPIN_LOCK_INIT;
|
||||
|
||||
kern_status_t console_register(console_t *con)
|
||||
{
|
||||
ml_console_init();
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&consoles_lock, &flags);
|
||||
|
||||
queue_foreach (console_t, cur, &consoles, c_list) {
|
||||
if (!strcmp(cur->c_name, con->c_name)) {
|
||||
spin_unlock_irqrestore(&consoles_lock, flags);
|
||||
return KERN_NAME_EXISTS;
|
||||
}
|
||||
}
|
||||
|
||||
queue_push_back(&consoles, &con->c_list);
|
||||
spin_unlock_irqrestore(&consoles_lock, flags);
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
void console_putchar(int c)
|
||||
kern_status_t console_unregister(console_t *con)
|
||||
{
|
||||
ml_console_putchar(c);
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&consoles_lock, &flags);
|
||||
|
||||
queue_delete(&consoles, &con->c_list);
|
||||
|
||||
spin_unlock_irqrestore(&consoles_lock, flags);
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
void console_write(console_t *con, const char *s, unsigned int len)
|
||||
{
|
||||
if (con->c_write) {
|
||||
con->c_write(con, s, len);
|
||||
}
|
||||
}
|
||||
|
||||
int console_read(console_t *con, char *s, unsigned int len)
|
||||
{
|
||||
int ret = -1;
|
||||
if (con->c_read) {
|
||||
ret = con->c_read(con, s, len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,74 @@
|
||||
#include <socks/printk.h>
|
||||
#include <socks/locks.h>
|
||||
#include <socks/console.h>
|
||||
#include <socks/libc/stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define LOG_BUFFER_SIZE 0x40000
|
||||
#define LOG_MSG_SIZE 0x100
|
||||
|
||||
static console_t *early_console = NULL;
|
||||
|
||||
static spin_lock_t log_buffer_lock = SPIN_LOCK_INIT;
|
||||
|
||||
static char log_buffer[LOG_BUFFER_SIZE] = {0};
|
||||
/* 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)
|
||||
{
|
||||
if (!early_console) {
|
||||
return;
|
||||
}
|
||||
|
||||
console_write(early_console, log_buffer + log_buffer_readp, log_buffer_writep - log_buffer_readp);
|
||||
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;
|
||||
}
|
||||
|
||||
log_buffer[log_buffer_writep++] = msg[i++];
|
||||
}
|
||||
}
|
||||
|
||||
void early_printk_init(console_t *con)
|
||||
{
|
||||
early_console = con;
|
||||
}
|
||||
|
||||
int printk(const char *format, ...)
|
||||
{
|
||||
(void)log_buffer;
|
||||
return 0;
|
||||
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';
|
||||
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&log_buffer_lock, &flags);
|
||||
save_log_message(msg);
|
||||
spin_unlock_irqrestore(&log_buffer_lock, flags);
|
||||
|
||||
flush_log_buffer();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user