diff --git a/common/cmdline.c b/common/cmdline.c index 0f64de19..385b9332 100644 --- a/common/cmdline.c +++ b/common/cmdline.c @@ -46,6 +46,9 @@ bool_cmd("hpet", opt_hpet); bool opt_fpu = false; bool_cmd("fpu", opt_fpu); +bool opt_qemu_console = false; +bool_cmd("qemu_console", opt_qemu_console); + const char *kernel_cmdline; void __text_init cmdline_parse(const char *cmdline) { diff --git a/common/console.c b/common/console.c index a32d7c8b..adf924b8 100644 --- a/common/console.c +++ b/common/console.c @@ -35,12 +35,9 @@ #include -#define QEMU_CONSOLE 0x0e9 -#define SERIAL_CONSOLE (com_ports[0]) - #define VPRINTK_BUF_SIZE 1024 -static console_callback_t console_callbacks[2]; +static console_callback_entry_t console_callbacks[2]; static unsigned int num_console_callbacks; static void vprintk(const char *fmt, va_list args) { @@ -56,8 +53,11 @@ static void vprintk(const char *fmt, va_list args) { if (rc > (int) sizeof(buf)) panic("vprintk() buffer overflow\n"); - for (i = 0; i < num_console_callbacks; i++) - console_callbacks[i](buf, rc); + for (i = 0; i < num_console_callbacks; i++) { + void *arg = console_callbacks[i].arg; + + console_callbacks[i].cb(arg, buf, rc); + } spin_unlock(&lock); } @@ -82,18 +82,25 @@ void AcpiOsPrintf(const char *Format, ...) { } #endif -void putchar(int c) { putc(SERIAL_CONSOLE, c); } +void serial_console_write(void *arg, const char *buf, size_t len) { + io_port_t port = (io_port_t) _ul(arg); -void serial_console_write(const char *buf, size_t len) { - serial_write(SERIAL_CONSOLE, buf, len); + serial_write(port, buf, len); } -void qemu_console_write(const char *buf, size_t len) { puts(QEMU_CONSOLE, buf, len); } +void qemu_console_write(void *arg, const char *buf, size_t len) { + io_port_t port = (io_port_t) _ul(arg); -void vga_console_write(const char *buf, size_t len) { vga_write(buf, len, VGA_WHITE); } + puts(port, buf, len); +} + +void vga_console_write(void *vga_memory, const char *buf, size_t len) { + vga_write(vga_memory, buf, len, VGA_WHITE); +} -void register_console_callback(console_callback_t cb) { - console_callbacks[num_console_callbacks++] = cb; +void register_console_callback(console_callback_t cb, void *arg) { + console_callbacks[num_console_callbacks].cb = cb; + console_callbacks[num_console_callbacks++].arg = arg; } void __noreturn panic(const char *fmt, ...) { diff --git a/common/setup.c b/common/setup.c index fd615200..bdcde46c 100644 --- a/common/setup.c +++ b/common/setup.c @@ -71,13 +71,19 @@ char cpu_identifier[49]; unsigned get_bsp_cpu_id(void) { return bsp_cpu_id; } void set_bsp_cpu_id(unsigned cpu_id) { bsp_cpu_id = cpu_id; } +#define QEMU_CONSOLE_PORT 0x0e9 static void __text_init init_console(void) { get_com_ports(); uart_init(com_ports[0], DEFAULT_BAUD_SPEED); - register_console_callback(serial_console_write); + register_console_callback(serial_console_write, _ptr(com_ports[0])); printk("COM1: %x, COM2: %x\n", com_ports[0], com_ports[1]); + + if (opt_qemu_console) { + register_console_callback(qemu_console_write, _ptr(QEMU_CONSOLE_PORT)); + printk("Initialized QEMU console at port 0x%x", QEMU_CONSOLE_PORT); + } } static __always_inline void zero_bss(void) { @@ -118,7 +124,7 @@ static void __text_init init_vga_console(void) { printk("Enabling VGA support\n"); map_vga_area(); - register_console_callback(vga_console_write); + register_console_callback(vga_console_write, paddr_to_virt_kern(VGA_START_ADDR)); } void __noreturn __text_init kernel_start(uint32_t multiboot_magic, diff --git a/drivers/vga.c b/drivers/vga.c index 49af217d..24efb224 100644 --- a/drivers/vga.c +++ b/drivers/vga.c @@ -50,7 +50,7 @@ void vga_scroll_up(void) { write_vga_buffer(--scroll_screen); } -void vga_write(const char *buf, size_t len, vga_color_t color) { +void vga_write(void *vga_memory, const char *buf, size_t len, vga_color_t color) { static int screen = 0, row = 0, col = 0; for (unsigned int i = 0; i < len; i++) { @@ -77,7 +77,7 @@ void vga_write(const char *buf, size_t len, vga_color_t color) { } scroll_screen = screen; - write_vga_buffer(screen); + memcpy(vga_memory, vga_buffer[screen], sizeof(vga_buffer[screen])); } void map_vga_area(void) { diff --git a/include/cmdline.h b/include/cmdline.h index 5b18b632..523dcaa3 100644 --- a/include/cmdline.h +++ b/include/cmdline.h @@ -63,6 +63,7 @@ extern bool opt_pit; extern bool opt_apic_timer; extern bool opt_hpet; extern bool opt_fpu; +extern bool opt_qemu_console; extern const char *kernel_cmdline; extern void cmdline_parse(const char *cmdline); diff --git a/include/console.h b/include/console.h index 2c08fb07..0d62b77c 100644 --- a/include/console.h +++ b/include/console.h @@ -27,7 +27,13 @@ #include -typedef void (*console_callback_t)(const char *buf, size_t len); +typedef void (*console_callback_t)(void *arg, const char *buf, size_t len); + +struct console_callback_entry { + console_callback_t cb; + void *arg; +}; +typedef struct console_callback_entry console_callback_entry_t; extern void printk(const char *fmt, ...); @@ -37,13 +43,11 @@ extern void printk(const char *fmt, ...); printk("%s (%s.%d): " fmt, __FILE__, __func__, __LINE__, ##__VA_ARGS__); \ } while (0) -extern void putchar(int c); - -extern void serial_console_write(const char *buf, size_t len); -extern void qemu_console_write(const char *buf, size_t len); -extern void vga_console_write(const char *buf, size_t len); +extern void serial_console_write(void *arg, const char *buf, size_t len); +extern void qemu_console_write(void *arg, const char *buf, size_t len); +extern void vga_console_write(void *arg, const char *buf, size_t len); -extern void register_console_callback(console_callback_t func); +extern void register_console_callback(console_callback_t func, void *arg); extern void panic(const char *fmt, ...); diff --git a/include/drivers/vga.h b/include/drivers/vga.h index 50bf3e6b..bde0425d 100644 --- a/include/drivers/vga.h +++ b/include/drivers/vga.h @@ -58,7 +58,7 @@ typedef enum vga_color vga_color_t; extern void vga_scroll_up(void); extern void vga_scroll_down(void); -extern void vga_write(const char *buf, size_t len, vga_color_t color); +extern void vga_write(void *vga_memory, const char *buf, size_t len, vga_color_t color); extern void map_vga_area(void); #endif /* KTF_DRV_VGA_H */