diff --git a/arch/amd64/hw/con.c b/arch/amd64/hw/con.c deleted file mode 100644 index 96aa862..0000000 --- a/arch/amd64/hw/con.c +++ /dev/null @@ -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 -} diff --git a/arch/amd64/hw/timer.c b/arch/amd64/hw/timer.c index 8e089fc..751272f 100644 --- a/arch/amd64/hw/timer.c +++ b/arch/amd64/hw/timer.c @@ -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; diff --git a/arch/amd64/hw/vesa.c b/arch/amd64/hw/vesa.c deleted file mode 100644 index 730388f..0000000 --- a/arch/amd64/hw/vesa.c +++ /dev/null @@ -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"); - } -} diff --git a/arch/amd64/kernel.c b/arch/amd64/kernel.c index f56c843..b86a208 100644 --- a/arch/amd64/kernel.c +++ b/arch/amd64/kernel.c @@ -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(); diff --git a/etc/make/amd64/config.mk b/etc/make/amd64/config.mk index c922686..cdf93e5 100644 --- a/etc/make/amd64/config.mk +++ b/etc/make/amd64/config.mk @@ -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 diff --git a/etc/make/amd64/platform.mk b/etc/make/amd64/platform.mk index b7ca91a..aa41601 100644 --- a/etc/make/amd64/platform.mk +++ b/etc/make/amd64/platform.mk @@ -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 \ diff --git a/include/sys/char/tty.h b/include/sys/char/tty.h index d2d36ab..b10bc58 100644 --- a/include/sys/char/tty.h +++ b/include/sys/char/tty.h @@ -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); diff --git a/include/sys/mem/phys.h b/include/sys/mem/phys.h index 331eb4e..4ca5355 100644 --- a/include/sys/mem/phys.h +++ b/include/sys/mem/phys.h @@ -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; diff --git a/sys/char/tty.c b/sys/char/tty.c index b9ff195..cdeaa17 100644 --- a/sys/char/tty.c +++ b/sys/char/tty.c @@ -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; } diff --git a/sys/debug.c b/sys/debug.c index 687d962..12808dd 100644 --- a/sys/debug.c +++ b/sys/debug.c @@ -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 } diff --git a/sys/mem/shmem.c b/sys/mem/shmem.c index 1218aef..5822f69 100644 --- a/sys/mem/shmem.c +++ b/sys/mem/shmem.c @@ -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"); } diff --git a/sys/wait.c b/sys/wait.c index f128fc5..5f7525a 100644 --- a/sys/wait.c +++ b/sys/wait.c @@ -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); } }