Remove old console code
This commit is contained in:
@@ -1,436 +0,0 @@
|
||||
#include "arch/amd64/hw/con.h"
|
||||
#include "user/termios.h"
|
||||
#include "arch/amd64/hw/io.h"
|
||||
#include "sys/string.h"
|
||||
#include "sys/types.h"
|
||||
#include "sys/debug.h"
|
||||
#include "sys/panic.h"
|
||||
#include "sys/spin.h"
|
||||
#include "sys/heap.h"
|
||||
#include "sys/mm.h"
|
||||
|
||||
#if defined(VESA_ENABLE)
|
||||
#include "arch/amd64/hw/vesa.h"
|
||||
#include "sys/font/psf.h"
|
||||
#include "sys/font/logo.h"
|
||||
#else
|
||||
#define vesa_available 0
|
||||
#endif
|
||||
|
||||
static spin_t display_lock = 0;
|
||||
|
||||
#define ESC_ESC 1
|
||||
#define ESC_CSI 2
|
||||
|
||||
#define CGA_BUFFER_ADDR 0xB8000
|
||||
#define ATTR_DEFAULT 0x1700ULL
|
||||
|
||||
#define ATTR_BOLD 1
|
||||
|
||||
static uint16_t *con_buffer;
|
||||
static uint16_t x = 0, y = 0;
|
||||
static uint16_t con_width, con_height;
|
||||
static uint16_t saved_x = 0, saved_y = 0;
|
||||
static int con_avail = 0;
|
||||
static uint16_t char_width, char_height;
|
||||
static int con_blink_state = 0;
|
||||
|
||||
// Map CSI colors to CGA
|
||||
static uint8_t color_map[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
|
||||
static uint32_t rgb_map[16] = {
|
||||
0x000000,
|
||||
0x0000AA,
|
||||
0x00AA00,
|
||||
0x00AAAA,
|
||||
0xAA0000,
|
||||
0xAA00AA,
|
||||
0xAA5500,
|
||||
0xAAAAAA,
|
||||
0x555555,
|
||||
0x5555FF,
|
||||
0x55FF55,
|
||||
0x55FFFF,
|
||||
0xFF5555,
|
||||
0xFF55FF,
|
||||
0xFFFF55,
|
||||
0xFFFFFF,
|
||||
};
|
||||
static uint32_t esc_argv[8];
|
||||
static size_t esc_argc;
|
||||
static char esc_letter = 0;
|
||||
static int esc_mode = 0;
|
||||
static uint16_t attr = ATTR_DEFAULT;
|
||||
static uint16_t xattr = 0;
|
||||
|
||||
static void setc(uint16_t row, uint16_t col, uint16_t v);
|
||||
|
||||
#if defined(VESA_ENABLE)
|
||||
static uint16_t old_blink_x, old_blink_y;
|
||||
|
||||
void con_blink(void) {
|
||||
if (vesa_available && !vesa_hold) {
|
||||
uint32_t fg = rgb_map[(attr >> 8) & 0xF];
|
||||
uint32_t bg = rgb_map[(attr >> 12) & 0xF];
|
||||
con_blink_state = !con_blink_state;
|
||||
|
||||
if (old_blink_x != x || old_blink_y != y) {
|
||||
uint16_t v = con_buffer[old_blink_y * con_width + old_blink_x];
|
||||
psf_draw(old_blink_y, old_blink_x, v & 0xFF, rgb_map[(v >> 8) & 0xF], rgb_map[(v >> 12) & 0xF]);
|
||||
}
|
||||
|
||||
uint16_t v = con_buffer[y * con_width + x];
|
||||
if (con_blink_state) {
|
||||
psf_draw(y, x, v & 0xFF, bg, fg);
|
||||
} else {
|
||||
psf_draw(y, x, v & 0xFF, fg, bg);
|
||||
}
|
||||
|
||||
old_blink_x = x;
|
||||
old_blink_y = y;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void amd64_con_sync_cursor(void) {
|
||||
static uint16_t old_pos = 0;
|
||||
uint16_t pos = y * 80 + x;
|
||||
|
||||
if (old_pos != pos) {
|
||||
// This is slow as hell
|
||||
outb(0x3D4, 0x0F);
|
||||
outb(0x3D5, (uint8_t) (pos & 0xFF));
|
||||
outb(0x3D4, 0x0E);
|
||||
outb(0x3D5, (uint8_t) ((pos >> 8) & 0xFF));
|
||||
}
|
||||
old_pos = pos;
|
||||
}
|
||||
|
||||
static void amd64_con_flush(void) {
|
||||
#if defined(VESA_ENABLE)
|
||||
if (vesa_available) {
|
||||
for (uint16_t row = 0; row < con_height; ++row) {
|
||||
for (uint16_t col = 0; col < con_width; ++col) {
|
||||
uint16_t v = con_buffer[row * con_width + col];
|
||||
psf_draw(row, col, v & 0xFF, rgb_map[(v >> 8) & 0xF], rgb_map[(v >> 12) & 0xF]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
memcpyq((uint64_t *) MM_VIRTUALIZE(CGA_BUFFER_ADDR), (uint64_t *) con_buffer, 25 * 20);
|
||||
}
|
||||
}
|
||||
|
||||
static void amd64_scroll_down(void) {
|
||||
#if defined(VESA_ENABLE)
|
||||
if (vesa_available && !vesa_hold) {
|
||||
memcpy(con_buffer, &con_buffer[con_width], (con_height - 1) * con_width * 2);
|
||||
memsetw(&con_buffer[(con_height - 1) * con_width], ATTR_DEFAULT, con_width);
|
||||
} else {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
memcpyq((uint64_t *) con_buffer, (uint64_t *) &con_buffer[con_width], 20 * 24);
|
||||
memsetq((uint64_t *) &con_buffer[(con_height - 1) * con_width],
|
||||
ATTR_DEFAULT | (ATTR_DEFAULT << 16) | (ATTR_DEFAULT << 32) | (ATTR_DEFAULT << 48), 20);
|
||||
}
|
||||
// Flush whole backbuffer
|
||||
amd64_con_flush();
|
||||
y = con_height - 1;
|
||||
}
|
||||
|
||||
static void clear(void) {
|
||||
memsetw(con_buffer, attr, con_width * con_height);
|
||||
#if defined(VESA_ENABLE)
|
||||
if (vesa_available) {
|
||||
for (size_t i = 0; i < vesa_height; ++i) {
|
||||
memsetl((uint32_t *) (vesa_addr + vesa_pitch * i), rgb_map[(attr >> 12) & 0xF], vesa_width);
|
||||
}
|
||||
}
|
||||
#else
|
||||
amd64_con_flush();
|
||||
#endif
|
||||
}
|
||||
|
||||
// I guess I could've implemented VT100 escape handling better, but
|
||||
// this is all I invented so far
|
||||
static void process_csi(void) {
|
||||
switch (esc_letter) {
|
||||
case 'm':
|
||||
for (size_t i = 0; i < esc_argc; ++i) {
|
||||
uint32_t v = esc_argv[i];
|
||||
switch (v / 10) {
|
||||
case 0:
|
||||
switch (v % 10) {
|
||||
case 0:
|
||||
// Reset
|
||||
attr = ATTR_DEFAULT;
|
||||
xattr = 0;
|
||||
break;
|
||||
case 1:
|
||||
// Bright
|
||||
xattr |= ATTR_BOLD;
|
||||
break;
|
||||
case 2:
|
||||
// Dim
|
||||
xattr &= ~ATTR_BOLD;
|
||||
break;
|
||||
case 7:
|
||||
// Reverse
|
||||
attr >>= 4;
|
||||
attr |= (attr & 0xF0) << 8;
|
||||
attr &= 0xFF00;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
// Foreground
|
||||
attr &= ~0x0F00;
|
||||
attr |= (uint16_t) color_map[v % 10] << 8;
|
||||
break;
|
||||
case 4:
|
||||
// Background
|
||||
attr &= ~0xF000;
|
||||
attr |= (uint16_t) color_map[v % 10] << 12;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'A':
|
||||
// Cursor up
|
||||
if (!esc_argv[0]) {
|
||||
esc_argv[0] = 1;
|
||||
}
|
||||
|
||||
if (esc_argv[0] >= y) {
|
||||
y = 0;
|
||||
} else {
|
||||
y -= esc_argv[0];
|
||||
}
|
||||
break;
|
||||
case 'B':
|
||||
// Cursor down
|
||||
if (!esc_argv[0]) {
|
||||
esc_argv[0] = 1;
|
||||
}
|
||||
|
||||
if (esc_argv[0] + y >= (uint32_t) (con_height - 1)) {
|
||||
y = 22;
|
||||
} else {
|
||||
y += esc_argv[0];
|
||||
}
|
||||
break;
|
||||
case 'C':
|
||||
// Forward
|
||||
if (!esc_argv[0]) {
|
||||
esc_argv[0] = 1;
|
||||
}
|
||||
|
||||
if (esc_argv[0] + x >= con_width) {
|
||||
x = 79;
|
||||
} else {
|
||||
x += esc_argv[0];
|
||||
}
|
||||
|
||||
break;
|
||||
case 'D':
|
||||
// Backward
|
||||
if (!esc_argv[0]) {
|
||||
esc_argv[0] = 1;
|
||||
}
|
||||
|
||||
if (esc_argv[0] >= x) {
|
||||
x = 0;
|
||||
} else {
|
||||
x -= esc_argv[0];
|
||||
}
|
||||
|
||||
break;
|
||||
case 'K':
|
||||
// Erase end of line
|
||||
memsetw(&con_buffer[y * con_width + x], attr, con_width - x);
|
||||
break;
|
||||
case 'J':
|
||||
switch (esc_argv[0]) {
|
||||
case 0:
|
||||
// Erase lines down
|
||||
memsetw(con_buffer, attr, con_width * y);
|
||||
break;
|
||||
case 1:
|
||||
// Erase lines up
|
||||
memsetw(&con_buffer[y * con_width], attr, con_width * (con_height - y));
|
||||
break;
|
||||
case 2:
|
||||
// Erase all
|
||||
clear();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
// Set cursor position
|
||||
y = (esc_argv[0] - 1) % con_height;
|
||||
x = (esc_argv[1] - 1) % (con_width - 1);
|
||||
break;
|
||||
case 's':
|
||||
// Save cursor
|
||||
saved_y = y;
|
||||
saved_x = x;
|
||||
break;
|
||||
case 'u':
|
||||
// Unsave cursor
|
||||
y = saved_y;
|
||||
x = saved_x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void setc(uint16_t row, uint16_t col, uint16_t v) {
|
||||
if (xattr & ATTR_BOLD) {
|
||||
v += 0x800;
|
||||
}
|
||||
|
||||
con_buffer[row * con_width + col] = v;
|
||||
|
||||
#if defined(VESA_ENABLE)
|
||||
if (vesa_available && !vesa_hold) {
|
||||
psf_draw(row, col, v & 0xFF, rgb_map[(v >> 8) & 0xF], rgb_map[(v >> 12) & 0xF]);
|
||||
} else {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
((uint16_t *) MM_VIRTUALIZE(CGA_BUFFER_ADDR))[row * 80 + col] = v;
|
||||
}
|
||||
}
|
||||
|
||||
void amd64_con_putc(int c) {
|
||||
if (!con_avail || !c) {
|
||||
// Ignore NULs
|
||||
return;
|
||||
}
|
||||
|
||||
c = (uint8_t) (c & 0xFF);
|
||||
|
||||
switch (esc_mode) {
|
||||
case ESC_CSI:
|
||||
if (c >= '0' && c <= '9') {
|
||||
esc_argv[esc_argc] *= 10;
|
||||
esc_argv[esc_argc] += c - '0';
|
||||
} else if (c == ';') {
|
||||
esc_argv[++esc_argc] = 0;
|
||||
} else {
|
||||
++esc_argc;
|
||||
esc_letter = c;
|
||||
process_csi();
|
||||
esc_mode = 0;
|
||||
}
|
||||
break;
|
||||
case ESC_ESC:
|
||||
if (c == '[') {
|
||||
esc_mode = ESC_CSI;
|
||||
break;
|
||||
} else {
|
||||
esc_mode = 0;
|
||||
}
|
||||
__attribute__((fallthrough));
|
||||
case 0:
|
||||
if (c == '\033') {
|
||||
esc_mode = ESC_ESC;
|
||||
esc_argv[0] = 0;
|
||||
esc_argc = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
if (c >= ' ') {
|
||||
setc(y, x, c | attr);
|
||||
++x;
|
||||
if (x >= con_width) {
|
||||
++y;
|
||||
x = 0;
|
||||
if (y == con_height) {
|
||||
amd64_scroll_down();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (c) {
|
||||
case '\n':
|
||||
++y;
|
||||
x = 0;
|
||||
if (y >= con_height) {
|
||||
amd64_scroll_down();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
amd64_con_putc('?');
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int pc_con_putc(void *dev, char c) {
|
||||
uintptr_t irq;
|
||||
spin_lock_irqsave(&display_lock, &irq);
|
||||
amd64_con_putc(c);
|
||||
spin_release_irqrestore(&display_lock, &irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void amd64_con_get_size(struct winsize *ws) {
|
||||
ws->ws_row = con_height;
|
||||
ws->ws_col = con_width;
|
||||
#if defined(VESA_ENABLE)
|
||||
if (vesa_available) {
|
||||
ws->ws_xpixel = vesa_width;
|
||||
ws->ws_ypixel = vesa_height;
|
||||
} else {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
ws->ws_xpixel = con_width;
|
||||
ws->ws_ypixel = con_height;
|
||||
}
|
||||
}
|
||||
|
||||
void amd64_con_init(void) {
|
||||
// XXX XXX XXX: Had to do this because of memory allocation problem:
|
||||
// setc overwrites data in heap headers
|
||||
static uint16_t second_buffer[80 * 25];
|
||||
#if defined(VESA_ENABLE)
|
||||
if (vesa_available) {
|
||||
psf_init(vesa_addr, vesa_pitch, &char_width, &char_height);
|
||||
|
||||
con_width = vesa_width / char_width;
|
||||
con_height = vesa_height / char_height;
|
||||
con_buffer = (uint16_t *) kmalloc(con_width * con_height * 2);
|
||||
} else {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
con_buffer = second_buffer;
|
||||
con_width = 80;
|
||||
con_height = 25;
|
||||
}
|
||||
con_avail = 1;
|
||||
|
||||
clear();
|
||||
|
||||
#if defined(VESA_ENABLE)
|
||||
if (vesa_available) {
|
||||
y = FONT_LOGO_HEIGHT / char_height;
|
||||
char pixel[4];
|
||||
char *data = font_logo_header_data;
|
||||
uint32_t v;
|
||||
for (uint32_t j = 0; j < FONT_LOGO_HEIGHT; ++j) {
|
||||
for (uint32_t i = 0; i < FONT_LOGO_WIDTH; ++i) {
|
||||
FONT_LOGO_HEADER_PIXEL(data, pixel);
|
||||
v = pixel[2] | ((uint32_t) pixel[1] << 8) | ((uint32_t) pixel[0] << 16);
|
||||
if (v) {
|
||||
vesa_put(i, j, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
+16
-16
@@ -28,8 +28,8 @@ static spin_t g_sleep_lock = 0;
|
||||
static LIST_HEAD(g_sleep_head);
|
||||
|
||||
void timer_add_sleep(struct thread *thr) {
|
||||
if (thr->pid > 0)
|
||||
kdebug("Adding %d to sleepers\n", thr->pid);
|
||||
//if (thr->pid > 0)
|
||||
//kdebug("Adding %d to sleepers\n", thr->pid);
|
||||
uintptr_t irq;
|
||||
struct io_notify *n = &thr->sleep_notify;
|
||||
spin_lock_irqsave(&g_sleep_lock, &irq);
|
||||
@@ -38,8 +38,8 @@ void timer_add_sleep(struct thread *thr) {
|
||||
}
|
||||
|
||||
void timer_remove_sleep(struct thread *thr) {
|
||||
if (thr->pid > 0)
|
||||
kdebug("Removing sleep %d\n", thr->pid);
|
||||
//if (thr->pid > 0)
|
||||
//kdebug("Removing sleep %d\n", thr->pid);
|
||||
uintptr_t irq;
|
||||
struct io_notify *n = &thr->sleep_notify;
|
||||
struct io_notify *it;
|
||||
@@ -58,18 +58,18 @@ void timer_remove_sleep(struct thread *thr) {
|
||||
static uint32_t timer_tick(void *arg) {
|
||||
switch ((uint64_t) arg) {
|
||||
case TIMER_PIT:
|
||||
#if defined(VESA_ENABLE)
|
||||
++int_timer_ticks;
|
||||
if (int_timer_ticks >= 300) {
|
||||
con_blink();
|
||||
int_timer_ticks = 0;
|
||||
}
|
||||
if (!vesa_available) {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
amd64_con_sync_cursor();
|
||||
}
|
||||
// #if defined(VESA_ENABLE)
|
||||
// ++int_timer_ticks;
|
||||
// if (int_timer_ticks >= 300) {
|
||||
// con_blink();
|
||||
// int_timer_ticks = 0;
|
||||
// }
|
||||
// if (!vesa_available) {
|
||||
//#else
|
||||
// {
|
||||
//#endif
|
||||
// amd64_con_sync_cursor();
|
||||
// }
|
||||
// Each tick is approx. 1ms, so add 1ms to system time
|
||||
system_time += 1000000;
|
||||
break;
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
#include "arch/amd64/multiboot2.h"
|
||||
#include "arch/amd64/hw/vesa.h"
|
||||
#include "sys/mem/vmalloc.h"
|
||||
#include "arch/amd64/cpu.h"
|
||||
#include "sys/block/blk.h"
|
||||
#include "sys/thread.h"
|
||||
#include "user/video.h"
|
||||
#include "user/errno.h"
|
||||
#include "sys/assert.h"
|
||||
#include "sys/string.h"
|
||||
#include "sys/panic.h"
|
||||
#include "sys/debug.h"
|
||||
#include "sys/dev.h"
|
||||
#include "sys/mm.h"
|
||||
|
||||
static int vesa_blk_ioctl(struct blkdev *blk, unsigned long cmd, void *arg);
|
||||
static void *vesa_blk_mmap(struct blkdev *blk, struct ofile *fd, void *hint, size_t length, int flags);
|
||||
|
||||
int vesa_hold = 0;
|
||||
int vesa_available = 0;
|
||||
uint64_t vesa_addr;
|
||||
uint32_t vesa_bpp, vesa_pitch, vesa_width, vesa_height;
|
||||
|
||||
static struct blkdev _vesa_fb0 = {
|
||||
.flags = 0,
|
||||
.dev_data = NULL,
|
||||
.read = NULL,
|
||||
.write = NULL,
|
||||
.ioctl = vesa_blk_ioctl,
|
||||
.mmap = vesa_blk_mmap
|
||||
};
|
||||
|
||||
static int vesa_blk_ioctl(struct blkdev *blk, unsigned long cmd, void *arg) {
|
||||
switch (cmd) {
|
||||
case IOC_GETVMODE:
|
||||
_assert(arg);
|
||||
((struct ioc_vmode *) arg)->width = vesa_width;
|
||||
((struct ioc_vmode *) arg)->height = vesa_height;
|
||||
return 0;
|
||||
case IOC_FBCON:
|
||||
_assert(arg);
|
||||
vesa_hold = !*(uint32_t *) arg;
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static void *vesa_blk_mmap(struct blkdev *blk, struct ofile *fd, void *hint, size_t length, int flags) {
|
||||
struct thread *thr = thread_self;
|
||||
_assert(thr);
|
||||
uintptr_t vaddr = vmfind(thr->space, 0x80000000, 0x100000000, length / MM_PAGE_SIZE);
|
||||
_assert(vaddr != MM_NADDR);
|
||||
uintptr_t phys = MM_PHYS(vesa_addr);
|
||||
|
||||
for (size_t i = 0; i < length / MM_PAGE_SIZE; ++i) {
|
||||
mm_map_single(thr->space, vaddr + i * MM_PAGE_SIZE, phys + i * MM_PAGE_SIZE, MM_PAGE_WRITE | MM_PAGE_USER, 0);
|
||||
}
|
||||
|
||||
return (void *) vaddr;
|
||||
}
|
||||
|
||||
void vesa_clear(uint32_t color) {
|
||||
if (vesa_hold) {
|
||||
return;
|
||||
}
|
||||
switch (vesa_bpp) {
|
||||
case 32:
|
||||
for (size_t i = 0; i < vesa_height; ++i) {
|
||||
memsetl((uint32_t *) (i * vesa_pitch + vesa_addr), color, vesa_width);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
panic("NYI\n");
|
||||
}
|
||||
}
|
||||
|
||||
void vesa_put(uint32_t x, uint32_t y, uint32_t v) {
|
||||
if (vesa_hold) {
|
||||
return;
|
||||
}
|
||||
switch (vesa_bpp) {
|
||||
case 32:
|
||||
((uint32_t *) (vesa_addr + vesa_pitch * y))[x] = v;
|
||||
break;
|
||||
default:
|
||||
panic("NYI\n");
|
||||
}
|
||||
}
|
||||
|
||||
void amd64_vesa_init(struct multiboot_tag_framebuffer *tag) {
|
||||
if (tag->common.framebuffer_type == 1) {
|
||||
vesa_available = 1;
|
||||
vesa_addr = MM_VIRTUALIZE(tag->common.framebuffer_addr);
|
||||
vesa_pitch = tag->common.framebuffer_pitch;
|
||||
vesa_width = tag->common.framebuffer_width;
|
||||
vesa_height = tag->common.framebuffer_height;
|
||||
vesa_bpp = tag->common.framebuffer_bpp;
|
||||
|
||||
kdebug("Set up VESA video:\n");
|
||||
kdebug("BPP: %d, Width: %d, Height: %d\n", vesa_bpp, vesa_width, vesa_height);
|
||||
kdebug("Addr: %p\n", vesa_addr);
|
||||
|
||||
dev_add(DEV_CLASS_BLOCK, DEV_BLOCK_OTHER, &_vesa_fb0, "fb0");
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -107,12 +107,12 @@ void kernel_early_init(void) {
|
||||
amd64_mm_init();
|
||||
|
||||
// Console can only be initialized after memory buffers can be allocated
|
||||
#if defined(VESA_ENABLE)
|
||||
if (multiboot_tag_framebuffer) {
|
||||
amd64_vesa_init(multiboot_tag_framebuffer);
|
||||
}
|
||||
amd64_con_init();
|
||||
#endif
|
||||
//#if defined(VESA_ENABLE)
|
||||
// if (multiboot_tag_framebuffer) {
|
||||
// amd64_vesa_init(multiboot_tag_framebuffer);
|
||||
// }
|
||||
// amd64_con_init();
|
||||
//#endif
|
||||
|
||||
ps2_register_device();
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ DEFINES+=-DVESA_ENABLE=1 \
|
||||
-DVESA_HEIGHT=$(VESA_HEIGHT) \
|
||||
-DVESA_DEPTH=$(VESA_DEPTH) \
|
||||
-DVESA_MODE=0
|
||||
OBJS+=$(O)/arch/amd64/hw/vesa.o
|
||||
#OBJS+=$(O)/arch/amd64/hw/vesa.o
|
||||
endif
|
||||
|
||||
### From config
|
||||
|
||||
@@ -45,8 +45,7 @@ OBJS+=$(ACPICA_OBJS) \
|
||||
$(O)/arch/amd64/sched_s.o \
|
||||
$(O)/arch/amd64/syscall_s.o \
|
||||
$(O)/arch/amd64/syscall.o \
|
||||
$(O)/arch/amd64/binfmt_elf.o \
|
||||
$(O)/arch/amd64/hw/con.o
|
||||
$(O)/arch/amd64/binfmt_elf.o
|
||||
|
||||
kernel_LINKER=arch/amd64/link.ld
|
||||
kernel_LDFLAGS=-nostdlib \
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
#pragma once
|
||||
#include "sys/types.h"
|
||||
|
||||
struct chrdev;
|
||||
|
||||
struct tty_data {
|
||||
// Process group ID of the foreground group (session leader)
|
||||
pid_t fg_pgid;
|
||||
// Output device info
|
||||
void *out_dev;
|
||||
int (*out_putc) (void *dev, char c);
|
||||
};
|
||||
|
||||
// From keyboard handlers and stuff
|
||||
void tty_control_write(struct chrdev *n, char c);
|
||||
void tty_data_write(struct chrdev *n, char c);
|
||||
|
||||
@@ -21,6 +21,7 @@ struct page {
|
||||
PU_UNKNOWN = 0,
|
||||
PU_PRIVATE, // Program data: image + mmap()ed anonymous regions
|
||||
PU_SHARED, // Shared memory mapping
|
||||
PU_DEVICE, // Possibly shared device mapping
|
||||
PU_KERNEL, // Not a userspace page
|
||||
} usage;
|
||||
size_t refcount;
|
||||
|
||||
+5
-63
@@ -23,19 +23,11 @@
|
||||
static ssize_t tty_write(struct chrdev *tty, const void *buf, size_t pos, size_t lim);
|
||||
static int tty_ioctl(struct chrdev *tty, unsigned int cmd, void *arg);
|
||||
|
||||
struct tty_data {
|
||||
// Process group ID of the foreground group (session leader)
|
||||
pid_t fg_pgid;
|
||||
// Output device info
|
||||
void *out_dev;
|
||||
int (*out_putc) (void *dev, char c);
|
||||
};
|
||||
|
||||
// Keyboard + display
|
||||
static struct tty_data _dev_tty0_data = {
|
||||
.fg_pgid = 1,
|
||||
.out_dev = 0,
|
||||
.out_putc = pc_con_putc
|
||||
.out_dev = NULL,
|
||||
.out_putc = NULL, //pc_con_putc
|
||||
};
|
||||
|
||||
static struct chrdev _dev_tty0 = {
|
||||
@@ -48,23 +40,6 @@ static struct chrdev _dev_tty0 = {
|
||||
.ioctl = tty_ioctl
|
||||
};
|
||||
|
||||
// Serial console
|
||||
//static struct tty_data _dev_ttyS0_data = {
|
||||
// .fg_pgid = 1,
|
||||
// .out_dev = (void *) RS232_COM1,
|
||||
// .out_putc = rs232_putc
|
||||
//};
|
||||
|
||||
//static struct chrdev _dev_ttyS0 = {
|
||||
// .type = CHRDEV_TTY,
|
||||
// .dev_data = &_dev_ttyS0_data,
|
||||
// .tc = TERMIOS_DEFAULT,
|
||||
// .write = tty_write,
|
||||
// // Line discipline
|
||||
// .read = line_read,
|
||||
// .ioctl = tty_ioctl
|
||||
//};
|
||||
|
||||
void tty_control_write(struct chrdev *tty, char c) {
|
||||
struct tty_data *data = tty->dev_data;
|
||||
_assert(data);
|
||||
@@ -126,8 +101,8 @@ void tty_puts(struct chrdev *tty, const char *s) {
|
||||
void tty_putc(struct chrdev *tty, char c) {
|
||||
struct tty_data *data = tty->dev_data;
|
||||
_assert(data);
|
||||
_assert(data->out_putc);
|
||||
data->out_putc(data->out_dev, c);
|
||||
//_assert(data->out_putc);
|
||||
//data->out_putc(data->out_dev, c);
|
||||
}
|
||||
|
||||
void tty_init(void) {
|
||||
@@ -143,42 +118,9 @@ void tty_init(void) {
|
||||
}
|
||||
|
||||
static ssize_t tty_write(struct chrdev *tty, const void *buf, size_t pos, size_t lim) {
|
||||
struct tty_data *data = tty->dev_data;
|
||||
_assert(data);
|
||||
_assert(data->out_putc);
|
||||
for (size_t i = 0; i < lim; ++i) {
|
||||
// This is printed as-is without tty_putc wrapper
|
||||
data->out_putc(data->out_dev, ((const char *) buf)[i]);
|
||||
}
|
||||
return lim;
|
||||
}
|
||||
|
||||
static int tty_ioctl(struct chrdev *tty, unsigned int cmd, void *arg) {
|
||||
struct tty_data *data = tty->dev_data;
|
||||
_assert(data);
|
||||
|
||||
switch (cmd) {
|
||||
case TCGETS:
|
||||
memcpy(arg, &tty->tc, sizeof(struct termios));
|
||||
return 0;
|
||||
case TCSETS:
|
||||
memcpy(&tty->tc, arg, sizeof(struct termios));
|
||||
if (tty->tc.c_iflag & ICANON) {
|
||||
tty->buffer.flags &= ~RING_RAW;
|
||||
} else {
|
||||
tty->buffer.flags |= RING_RAW;
|
||||
}
|
||||
return 0;
|
||||
case TIOCGWINSZ:
|
||||
// TODO: See comment on tty data struct
|
||||
amd64_con_get_size(arg);
|
||||
return 0;
|
||||
case TIOCSPGRP:
|
||||
// Clear interrupts and stuff
|
||||
tty->buffer.flags = 0;
|
||||
data->fg_pgid = *(pid_t *) arg;
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+3
-3
@@ -197,9 +197,9 @@ void debugc(int level, char c) {
|
||||
if (DEBUG_SERIAL(level) & kernel_config[CFG_DEBUG]) {
|
||||
rs232_send(RS232_COM1, c);
|
||||
}
|
||||
if (DEBUG_DISP(level) & kernel_config[CFG_DEBUG]) {
|
||||
amd64_con_putc(c);
|
||||
}
|
||||
//if (DEBUG_DISP(level) & kernel_config[CFG_DEBUG]) {
|
||||
// amd64_con_putc(c);
|
||||
//}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+43
-1
@@ -61,8 +61,40 @@ void *sys_mmap(void *hint, size_t length, int prot, int flags, int fd, off_t off
|
||||
// Anonymous mapping
|
||||
return sys_mmap_anon(page_count, prot, flags);
|
||||
} else {
|
||||
struct thread *thr = thread_self;
|
||||
|
||||
// File/device-backed mapping
|
||||
panic("TODO\n");
|
||||
if (fd < 0 || fd >= THREAD_MAX_FDS) {
|
||||
return (void *) -EBADF;
|
||||
}
|
||||
|
||||
struct ofile *of = thr->fds[fd];
|
||||
if (!of) {
|
||||
return (void *) -EBADF;
|
||||
}
|
||||
|
||||
if (of->flags & OF_SOCKET) {
|
||||
return (void *) -EINVAL;
|
||||
}
|
||||
|
||||
struct vnode *vn = of->file.vnode;
|
||||
_assert(vn);
|
||||
|
||||
switch (vn->type) {
|
||||
case VN_BLK:
|
||||
{
|
||||
struct blkdev *blk = vn->dev;
|
||||
_assert(blk);
|
||||
|
||||
if (!blk->mmap) {
|
||||
return (void *) -EINVAL;
|
||||
}
|
||||
|
||||
return blk->mmap(blk, of, hint, length, flags);
|
||||
}
|
||||
default:
|
||||
return (void *) -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +122,8 @@ int sys_munmap(void *ptr, size_t len) {
|
||||
|
||||
len /= MM_PAGE_SIZE;
|
||||
|
||||
// TODO: If it's a device mapping, notify device a page was unmapped
|
||||
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
uint64_t flags;
|
||||
uintptr_t phys = mm_map_get(thr->space, addr + i * MM_PAGE_SIZE, &flags);
|
||||
@@ -101,6 +135,14 @@ int sys_munmap(void *ptr, size_t len) {
|
||||
struct page *page = PHYS2PAGE(phys);
|
||||
_assert(page);
|
||||
|
||||
// TODO: FIX THIS
|
||||
if (page->usage == PU_DEVICE) {
|
||||
_assert(page->refcount);
|
||||
_assert(mm_umap_single(thr->space, addr + i * MM_PAGE_SIZE, 1) == phys);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(page->flags & PG_MMAPED)) {
|
||||
panic("Tried to unmap non-mmapped page\n");
|
||||
}
|
||||
|
||||
@@ -53,6 +53,12 @@ void thread_notify_io(struct io_notify *n) {
|
||||
spin_release_irqrestore(&n->lock, &irq);
|
||||
|
||||
if (t) {
|
||||
// Prevent double task wakeup when
|
||||
// two event sources simultaneously try
|
||||
// to do it
|
||||
if (t->sched_next) {
|
||||
return;
|
||||
}
|
||||
sched_queue(t);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user