1 #include <klibc/string.h>
2 #include <lunaix/lxconsole.h>
3 #include <lunaix/mm/pmm.h>
4 #include <lunaix/mm/vmm.h>
5 #include <lunaix/tty/console.h>
6 #include <lunaix/tty/tty.h>
8 static struct console lx_console;
10 volatile int can_flush = 0;
15 memset(&lx_console, 0, sizeof(lx_console));
16 lx_console.buffer.data = VGA_BUFFER_VADDR + 0x1000;
17 lx_console.buffer.size = 8192;
18 mutex_init(&lx_console.buffer.lock);
21 for (size_t i = 0; i < PG_ALIGN(lx_console.buffer.size); i += PG_SIZE) {
22 uintptr_t pa = pmm_alloc_page(KERNEL_PID, 0);
23 vmm_set_mapping(PD_REFERENCED,
24 (uintptr_t)lx_console.buffer.data + i,
30 memset(lx_console.buffer.data, 0, lx_console.buffer.size);
32 lx_console.flush_timer = NULL;
36 console_schedule_flush()
38 // TODO make the flush on-demand rather than periodic
42 console_view_up(struct fifo_buffer* buffer)
44 // mutex_lock(&buffer->lock);
45 size_t p = buffer->rd_pos - 2;
46 while (p < buffer->rd_pos && p != buffer->wr_pos &&
47 ((char*)buffer->data)[p] != '\n') {
52 if (p < buffer->rd_pos) {
57 // mutex_unlock(&buffer->lock);
61 console_view_down(struct fifo_buffer* buffer)
63 // mutex_lock(&buffer->lock);
64 size_t p = buffer->rd_pos;
65 while (p != buffer->wr_pos && ((char*)buffer->data)[p] != '\n') {
66 p = (p + 1) % buffer->size;
69 buffer->rd_pos = p + 1;
70 // mutex_unlock(&buffer->lock);
76 if (mutex_on_hold(&lx_console.buffer.lock)) {
79 if (!(lx_console.buffer.flags & FIFO_DIRTY)) {
83 size_t pos = tty_flush_buffer(lx_console.buffer.data,
84 lx_console.buffer.rd_pos,
85 lx_console.buffer.wr_pos,
86 lx_console.buffer.size);
87 lx_console.flush_timer = NULL;
88 if (pos < lx_console.buffer.wr_pos) {
89 console_view_down(&lx_console.buffer);
91 // clear the dirty bit only if we have flush all the data
92 // that means: read pointer == write pointer
93 lx_console.buffer.flags &= ~FIFO_DIRTY;
98 console_write(struct console* console, uint8_t* data, size_t size)
100 mutex_lock(&console->buffer.lock);
101 uint8_t* buffer = console->buffer.data;
102 uintptr_t ptr = console->buffer.wr_pos;
103 uintptr_t rd_ptr = console->buffer.rd_pos;
105 for (size_t i = 0; i < size; i++) {
106 buffer[(ptr + i) % console->buffer.size] = data[i];
109 uintptr_t new_ptr = (ptr + size) % console->buffer.size;
110 console->buffer.wr_pos = new_ptr;
111 if (new_ptr < ptr + size && new_ptr > rd_ptr) {
112 console->buffer.rd_pos = new_ptr;
114 console->buffer.flags |= FIFO_DIRTY;
115 mutex_unlock(&console->buffer.lock);
119 console_write_str(char* str)
121 console_write(&lx_console, str, strlen(str));
125 console_write_char(char str)
127 console_write(&lx_console, &str, 1);
131 console_start_flushing()
133 struct lx_timer* timer =
134 timer_run_ms(20, __flush_cb, NULL, TIMER_MODE_PERIODIC);
135 lx_console.flush_timer = timer;