summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/isa/spkr.c53
-rw-r--r--sys/dev/cons/cons.c27
-rw-r--r--sys/dev/cons/cons_ansi.c165
-rw-r--r--sys/dev/usb/xhci.c6
-rw-r--r--sys/dev/video/fbdev.c49
-rw-r--r--sys/include/dev/cons/ansi.h74
-rw-r--r--sys/include/dev/cons/cons.h4
-rw-r--r--sys/include/sys/device.h2
-rw-r--r--sys/include/sys/fbdev.h40
-rw-r--r--sys/include/sys/mman.h22
-rw-r--r--sys/include/sys/syscall.h2
-rw-r--r--sys/kern/kern_stub.c12
-rw-r--r--sys/kern/kern_syscall.c3
-rw-r--r--sys/vm/vm_map.c49
14 files changed, 475 insertions, 33 deletions
diff --git a/sys/arch/amd64/isa/spkr.c b/sys/arch/amd64/isa/spkr.c
index b1bd2a2..b2f63b0 100644
--- a/sys/arch/amd64/isa/spkr.c
+++ b/sys/arch/amd64/isa/spkr.c
@@ -30,14 +30,60 @@
#include <sys/cdefs.h>
#include <sys/errno.h>
#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/driver.h>
+#include <fs/devfs.h>
#include <dev/timer.h>
#include <machine/isa/spkr.h>
#include <machine/isa/i8254.h>
#include <machine/pio.h>
+#include <string.h>
#define DIVIDEND 1193180
#define CTRL_PORT 0x61
+static struct cdevsw beep_cdevsw;
+
+/*
+ * Write to the pcspkr
+ *
+ * Bits 15:0 - frequency (hz)
+ * Bits 31:16 - duration (msec)
+ */
+static int
+dev_write(dev_t dev, struct sio_txn *sio, int flags)
+{
+ uint32_t payload = 0;
+ uint16_t hz;
+ uint16_t duration;
+ size_t len = sizeof(payload);
+
+ if (sio->len < len) {
+ return -EINVAL;
+ }
+
+ memcpy(&payload, sio->buf, len);
+ hz = payload & 0xFFFF;
+ duration = (payload >> 16) & 0xFFFF;
+ pcspkr_tone(hz, duration);
+ return sio->len;
+}
+
+static int
+beep_init(void)
+{
+ char devname[] = "beep";
+ devmajor_t major;
+ dev_t dev;
+
+ /* Register the device here */
+ major = dev_alloc_major();
+ dev = dev_alloc(major);
+ dev_register(major, dev, &beep_cdevsw);
+ devfs_create_entry(devname, major, dev, 0666);
+ return 0;
+}
+
int
pcspkr_tone(uint16_t freq, uint32_t msec)
{
@@ -67,3 +113,10 @@ pcspkr_tone(uint16_t freq, uint32_t msec)
outb(CTRL_PORT, tmp & ~3);
return 0;
}
+
+static struct cdevsw beep_cdevsw = {
+ .read = noread,
+ .write = dev_write
+};
+
+DRIVER_EXPORT(beep_init);
diff --git a/sys/dev/cons/cons.c b/sys/dev/cons/cons.c
index 61254a7..671d5f0 100644
--- a/sys/dev/cons/cons.c
+++ b/sys/dev/cons/cons.c
@@ -158,6 +158,8 @@ cons_handle_special(struct cons_screen *scr, char c)
}
switch (c) {
+ case ASCII_NUL:
+ return 0;
case ASCII_BS:
bp = scr->ob[scr->ch_row];
if (bp->head > bp->tail) {
@@ -262,6 +264,14 @@ cons_fast_putch(struct cons_screen *scr, char c)
{
struct cons_char cc;
struct cons_buf *bp;
+ int ansi;
+
+ ansi = ansi_feed(&scr->ansi_s, c);
+ if (ansi > 0) {
+ c = ASCII_NUL;
+ } else if (ansi < 0) {
+ c = ASCII_NUL;
+ }
/* Handle specials */
if (cons_handle_special(scr, c) == 0) {
@@ -379,6 +389,23 @@ cons_init_bufs(struct cons_screen *scr)
}
/*
+ * Reset console color.
+ */
+void
+cons_reset_color(struct cons_screen *scr)
+{
+ g_root_scr.fg = CONSOLE_FG;
+ g_root_scr.bg = CONSOLE_BG;
+}
+
+void
+cons_update_color(struct cons_screen *scr, uint32_t fg, uint32_t bg)
+{
+ scr->fg = fg;
+ scr->bg = bg;
+}
+
+/*
* Put a character on the screen.
*
* @scr: Screen.
diff --git a/sys/dev/cons/cons_ansi.c b/sys/dev/cons/cons_ansi.c
new file mode 100644
index 0000000..a91f1d3
--- /dev/null
+++ b/sys/dev/cons/cons_ansi.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <dev/cons/cons.h>
+#include <dev/cons/ansi.h>
+#include <string.h>
+
+__always_inline static inline bool
+is_valid_color(int c)
+{
+ return c >= '0' && c <= '7';
+}
+
+static inline void
+ansi_reset(struct ansi_state *statep)
+{
+ memset(statep, 0, sizeof(*statep));
+}
+
+/*
+ * Feed a byte into the ANSI escape sequence
+ * state machine.
+ *
+ * @statep: State machine pointer.
+ * @c: Byte to feed.
+ *
+ * On success, `c' is returned. On failure,
+ * 0 is returned. Values less than 0 indicate
+ * success with console attributes updated
+ * (ANSI_UPDATE_*).
+ */
+int
+ansi_feed(struct ansi_state *statep, char c)
+{
+ /* Standard colors */
+ static uint32_t colortab[] = {
+ ANSI_BLACK, ANSI_RED,
+ ANSI_GREEN, ANSI_YELLOW,
+ ANSI_BLUE, ANSI_MAGENTA,
+ ANSI_CYAN, ANSI_WHITE
+ };
+
+ /*
+ * Handle the control sequence introducer
+ * bytes.
+ */
+ switch (statep->csi) {
+ case 0: /* '\033' */
+ if (c != '\033') {
+ return 0;
+ }
+ statep->csi = 1;
+ statep->prev = c;
+ return c;
+ case 1: /* '[' */
+ if (c != '[') {
+ ansi_reset(statep);
+ return 0;
+ }
+ statep->csi = 2;
+ statep->prev = c;
+ return c;
+ }
+
+ if (!statep->set_fg && !statep->set_bg) {
+ /* Reset attributes? */
+ if (statep->reset_color) {
+ ansi_reset(statep);
+ cons_reset_color(&g_root_scr);
+ return ANSI_UPDATE_COLOR;
+ }
+
+ /* Mark attributes to be reset? */
+ if (c == '0') {
+ statep->reset_color = 1;
+ statep->prev = c;
+ return c;
+ }
+
+ /* Expect foreground */
+ if (c != '3') {
+ ansi_reset(statep);
+ return 0;
+ }
+ statep->set_fg = 1;
+ statep->prev = c;
+ return c;
+ }
+
+ if (statep->set_fg && c != ';') {
+ /* Make sure this is valid */
+ if (!is_valid_color(c)) {
+ ansi_reset(statep);
+ return 0;
+ }
+
+ /* Set the foreground */
+ statep->fg = colortab[c - '0'];
+ statep->set_bg = 1;
+ statep->set_fg = 0;
+ statep->prev = c;
+ return c;
+ }
+
+ if (statep->set_bg) {
+ if (c == ';') {
+ statep->prev = c;
+ return c;
+ }
+
+ /* Expect '4' after ';' */
+ if (statep->prev == ';' && c != '4') {
+ ansi_reset(statep);
+ return 0;
+ }
+
+ if (c == 'm') {
+ cons_update_color(&g_root_scr, statep->fg, statep->bg);
+ ansi_reset(statep);
+ return ANSI_UPDATE_COLOR;
+ }
+
+ /* Make sure this is valid */
+ if (!is_valid_color(c)) {
+ ansi_reset(statep);
+ return 0;
+ }
+
+ /* Set the background */
+ statep->bg = colortab[c - '0'];
+ statep->prev = c;
+ return c;
+ }
+
+ ansi_reset(statep);
+ return 0;
+}
diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c
index 5276eea..2b55f16 100644
--- a/sys/dev/usb/xhci.c
+++ b/sys/dev/usb/xhci.c
@@ -176,6 +176,7 @@ xhci_init_scratchpads(struct xhci_hc *hc)
struct xhci_caps *caps = XHCI_CAPS(hc->base);
uint16_t max_bufs_lo, max_bufs_hi;
uint16_t max_bufs;
+ uint32_t npages;
uintptr_t *bufarr, tmp;
max_bufs_lo = XHCI_MAX_SP_LO(caps->hcsparams1);
@@ -189,8 +190,9 @@ xhci_init_scratchpads(struct xhci_hc *hc)
return 0;
}
- pr_trace("using %d pages for xHC scratchpads\n");
- bufarr = dynalloc_memalign(sizeof(uintptr_t)*max_bufs, 0x1000);
+ npages = (sizeof(uint64_t) * max_bufs) / DEFAULT_PAGESIZE;
+ pr_trace("using %d pages for xHC scratchpads\n", npages);
+ bufarr = dynalloc_memalign(npages * DEFAULT_PAGESIZE, 0x1000);
if (bufarr == NULL) {
pr_error("failed to allocate scratchpad buffer array\n");
return -1;
diff --git a/sys/dev/video/fbdev.c b/sys/dev/video/fbdev.c
index 391400c..8a2499d 100644
--- a/sys/dev/video/fbdev.c
+++ b/sys/dev/video/fbdev.c
@@ -28,36 +28,65 @@
*/
#include <sys/types.h>
+#include <sys/errno.h>
#include <sys/limine.h>
#include <sys/device.h>
#include <sys/driver.h>
+#include <sys/fbdev.h>
#include <dev/video/fbdev.h>
#include <fs/devfs.h>
+#include <fs/ctlfs.h>
#include <vm/vm.h>
+#include <string.h>
#define FRAMEBUFFER \
framebuffer_req.response->framebuffers[0]
static struct cdevsw fb_cdevsw;
+static const struct ctlops fb_size_ctl;
static volatile struct limine_framebuffer_request framebuffer_req = {
.id = LIMINE_FRAMEBUFFER_REQUEST,
.revision = 0
};
static paddr_t
-fbdev_mmap(dev_t dev, off_t off, int flags)
+fbdev_mmap(dev_t dev, size_t size, off_t off, int flags)
{
size_t max_bounds;
max_bounds = FRAMEBUFFER->pitch * FRAMEBUFFER->height;
- max_bounds /= 4;
- if (off > max_bounds) {
+ if ((off + size) > max_bounds) {
return 0;
}
return VIRT_TO_PHYS(FRAMEBUFFER->address);
}
+static int
+ctl_attr_read(struct ctlfs_dev *cdp, struct sio_txn *sio)
+{
+ struct fbattr attr;
+ size_t len = sizeof(attr);
+
+ if (sio == NULL) {
+ return -EINVAL;
+ }
+ if (sio->buf == NULL) {
+ return -EINVAL;
+ }
+
+ if (len > sio->len) {
+ len = sio->len;
+ }
+
+ attr.width = FRAMEBUFFER->width;
+ attr.height = FRAMEBUFFER->height;
+ attr.pitch = FRAMEBUFFER->pitch;
+ attr.bpp = FRAMEBUFFER->bpp;
+ memcpy(sio->buf, &attr, len);
+ return len;
+}
+
struct fbdev
fbdev_get(void)
{
@@ -74,6 +103,7 @@ fbdev_get(void)
static int
fbdev_init(void)
{
+ struct ctlfs_dev ctl;
char devname[] = "fb0";
devmajor_t major;
dev_t dev;
@@ -83,6 +113,14 @@ fbdev_init(void)
dev = dev_alloc(major);
dev_register(major, dev, &fb_cdevsw);
devfs_create_entry(devname, major, dev, 0444);
+
+
+ /* Register control files */
+ ctl.mode = 0444;
+ ctlfs_create_node(devname, &ctl);
+ ctl.devname = devname;
+ ctl.ops = &fb_size_ctl;
+ ctlfs_create_entry("attr", &ctl);
return 0;
}
@@ -92,4 +130,9 @@ static struct cdevsw fb_cdevsw = {
.mmap = fbdev_mmap
};
+static const struct ctlops fb_size_ctl = {
+ .read = ctl_attr_read,
+ .write = NULL,
+};
+
DRIVER_EXPORT(fbdev_init);
diff --git a/sys/include/dev/cons/ansi.h b/sys/include/dev/cons/ansi.h
new file mode 100644
index 0000000..98d7618
--- /dev/null
+++ b/sys/include/dev/cons/ansi.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CONS_ANSI_H_
+#define _CONS_ANSI_H_
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <sys/param.h>
+
+/* ANSI colors */
+#define ANSI_BLACK 0x000000
+#define ANSI_RED 0xAA0000
+#define ANSI_GREEN 0x00AA00
+#define ANSI_BLUE 0x0000AA
+#define ANSI_YELLOW 0xAA5500
+#define ANSI_MAGENTA 0xAA00AA
+#define ANSI_CYAN 0x00AAAA
+#define ANSI_WHITE 0xAAAAAA
+
+/* ANSI_FEED update codes */
+#define ANSI_UPDATE_COLOR -1
+
+/*
+ * ANSI parser state machine.
+ *
+ * @prev: Previous char
+ * @csi: Encountered control seq introducer
+ * @reset_color: 1 if color is to be reset
+ * @set_fg: 1 if fg is being set
+ * @set_bg: 1 if bg is being set
+ * @fg: Foreground color
+ * @bg: Background color
+ * @flags: State flags
+ */
+struct ansi_state {
+ char prev;
+ uint8_t csi : 2;
+ uint8_t reset_color : 1;
+ uint8_t set_fg : 1;
+ uint8_t set_bg : 1;
+ uint32_t fg;
+ uint32_t bg;
+};
+
+int ansi_feed(struct ansi_state *statep, char c);
+
+#endif /* !_CONS_ANSI_H_ */
diff --git a/sys/include/dev/cons/cons.h b/sys/include/dev/cons/cons.h
index b27be23..13153b2 100644
--- a/sys/include/dev/cons/cons.h
+++ b/sys/include/dev/cons/cons.h
@@ -34,6 +34,7 @@
#include <sys/spinlock.h>
#include <dev/video/fbdev.h>
#include <dev/cons/consvar.h>
+#include <dev/cons/ansi.h>
struct cons_char {
char c;
@@ -45,6 +46,7 @@ struct cons_char {
struct cons_screen {
struct fbdev fbdev;
+ struct ansi_state ansi_s;
uint32_t fg;
uint32_t bg;
@@ -64,6 +66,8 @@ struct cons_screen {
void cons_init(void);
void cons_expose(void);
+void cons_update_color(struct cons_screen *scr, uint32_t fg, uint32_t bg);
+void cons_reset_color(struct cons_screen *scr);
int cons_putch(struct cons_screen *scr, char c);
int cons_putstr(struct cons_screen *scr, const char *s, size_t len);
diff --git a/sys/include/sys/device.h b/sys/include/sys/device.h
index cb2a702..04b66fc 100644
--- a/sys/include/sys/device.h
+++ b/sys/include/sys/device.h
@@ -48,7 +48,7 @@ typedef int(*dev_bsize_t)(dev_t);
struct cdevsw {
int(*read)(dev_t dev, struct sio_txn *sio, int flags);
int(*write)(dev_t dev, struct sio_txn *sio, int flags);
- paddr_t(*mmap)(dev_t dev, off_t off, int flags);
+ paddr_t(*mmap)(dev_t dev, size_t size, off_t off, int flags);
/* Private */
struct vm_object vmobj;
diff --git a/sys/include/sys/fbdev.h b/sys/include/sys/fbdev.h
new file mode 100644
index 0000000..e206889
--- /dev/null
+++ b/sys/include/sys/fbdev.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_FBDEV_H_
+#define _SYS_FBDEV_H_
+
+struct fbattr {
+ uint32_t width;
+ uint32_t height;
+ uint32_t pitch;
+ uint32_t bpp;
+};
+
+#endif /* !_SYS_FBDEV_H_ */
diff --git a/sys/include/sys/mman.h b/sys/include/sys/mman.h
index 4ead9ba..08f506d 100644
--- a/sys/include/sys/mman.h
+++ b/sys/include/sys/mman.h
@@ -35,6 +35,8 @@
#if defined(_KERNEL)
#include <sys/tree.h>
#include <vm/vm_obj.h>
+#else
+#include <stddef.h>
#endif /* _KERNEL */
/*
@@ -80,19 +82,19 @@ struct mmap_lgdr {
size_t nbytes;
};
-/* Kernel munmap() routine */
-int munmap_at(void *addr, size_t len);
-
-/* Kernel mmap() routine */
-void *mmap_at(void *addr, size_t len, int prot, int flags,
- int fildes, off_t off);
-
int mmap_entrycmp(const struct mmap_entry *a, const struct mmap_entry *b);
RBT_PROTOTYPE(lgdr_entries, mmap_entry, hd, mmap_entrycmp)
-#endif /* _KERNEL */
/* Syscall layer */
-scret_t mmap(struct syscall_args *scargs);
-scret_t munmap(struct syscall_args *scargs);
+scret_t sys_mmap(struct syscall_args *scargs);
+scret_t sys_munmap(struct syscall_args *scargs);
+#endif /* _KERNEL */
+
+/* Kernel munmap() routine */
+int munmap(void *addr, size_t len);
+
+/* Kernel mmap() routine */
+void *mmap(void *addr, size_t len, int prot, int flags,
+ int fildes, off_t off);
#endif /* !_SYS_MMAN_H_ */
diff --git a/sys/include/sys/syscall.h b/sys/include/sys/syscall.h
index 2223a96..dad2e00 100644
--- a/sys/include/sys/syscall.h
+++ b/sys/include/sys/syscall.h
@@ -48,6 +48,8 @@
#define SYS_write 7
#define SYS_spawn 8
#define SYS_reboot 9
+#define SYS_mmap 10
+#define SYS_munmap 11
#if defined(_KERNEL)
/* Syscall return value and arg type */
diff --git a/sys/kern/kern_stub.c b/sys/kern/kern_stub.c
index fa1be65..17c6e54 100644
--- a/sys/kern/kern_stub.c
+++ b/sys/kern/kern_stub.c
@@ -40,7 +40,9 @@ sigfpe_default(int signo)
static struct proc *td;
td = this_td();
- kprintf("Floating point exception (pid=%d)\n", td->pid);
+ syslog_silence(false);
+ kprintf(OMIT_TIMESTAMP "Floating point exception (pid=%d)\n", td->pid);
+ syslog_silence(true);
exit1(td, 0);
}
@@ -50,7 +52,9 @@ sigkill_default(int signo)
static struct proc *td;
td = this_td();
- kprintf("Terminated (pid=%d)\n", td->pid);
+ syslog_silence(false);
+ kprintf(OMIT_TIMESTAMP "Terminated (pid=%d)\n", td->pid);
+ syslog_silence(true);
exit1(td, 0);
}
@@ -60,7 +64,9 @@ sigsegv_default(int signo)
static struct proc *td;
td = this_td();
- kprintf("Segmentation fault (pid=%d)\n", td->pid);
+ syslog_silence(false);
+ kprintf(OMIT_TIMESTAMP "Segmentation fault (pid=%d)\n", td->pid);
+ syslog_silence(true);
exit1(td, 0);
}
diff --git a/sys/kern/kern_syscall.c b/sys/kern/kern_syscall.c
index 249a04a..8a66f0e 100644
--- a/sys/kern/kern_syscall.c
+++ b/sys/kern/kern_syscall.c
@@ -31,6 +31,7 @@
#include <sys/sysctl.h>
#include <sys/reboot.h>
#include <sys/types.h>
+#include <sys/mman.h>
#include <sys/proc.h>
#include <sys/vfs.h>
@@ -45,6 +46,8 @@ scret_t(*g_sctab[])(struct syscall_args *) = {
sys_write, /* SYS_write */
sys_spawn, /* SYS_spawn */
sys_reboot, /* SYS_reboot */
+ sys_mmap, /* SYS_mmap */
+ sys_munmap, /* SYS_munap */
};
const size_t MAX_SYSCALLS = NELEM(g_sctab);
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index b8f4aee..26effdb 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -159,7 +159,7 @@ vm_map_modify(struct vas vas, vaddr_t va, paddr_t pa, vm_prot_t prot, bool unmap
* crashes.
*/
void *
-mmap_at(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
+mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
{
struct vm_object *map_obj = NULL;
struct cdevsw *cdevp;
@@ -173,17 +173,13 @@ mmap_at(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
paddr_t pa;
vaddr_t va;
size_t misalign;
+ off_t page_off;
misalign = len & (DEFAULT_PAGESIZE - 1);
len = ALIGN_UP(len + misalign, DEFAULT_PAGESIZE);
npgs = len / DEFAULT_PAGESIZE;
vas = pmap_read_vas();
- if (addr == NULL) {
- pr_error("mmap: NULL addr not supported\n");
- return NULL;
- }
-
/* Validate flags */
if (ISSET(flags, MAP_FIXED)) {
pr_error("mmap: fixed mappings not yet supported\n");
@@ -216,11 +212,29 @@ mmap_at(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
}
cdevp = map_obj->data;
- if ((pa = cdevp->mmap(vp->dev, off, 0)) == 0) {
+ if ((pa = cdevp->mmap(vp->dev, len, off, 0)) == 0) {
kprintf("mmap: dev mmap() gave 0\n");
return NULL;
}
+ /*
+ * If the address passed is NULL, just identity
+ * map everything.
+ *
+ * XXX: This is why the bounds check done in the
+ * cdev mmap() *must* be correct.
+ *
+ * TODO: Use copy-on-write for this instead. Since mapping
+ * certain devices may required a lot of memory to
+ * be referenced anyways, we could use a buffered
+ * copy-on-write technique where only a window of
+ * pages can be mapped on-demand and other pages
+ * freed when that window is exceeded.
+ */
+ if (addr == NULL) {
+ addr = (void *)pa;
+ }
+
va = ALIGN_DOWN((vaddr_t)addr, DEFAULT_PAGESIZE);
error = vm_map(vas, va, pa, prot, len);
if (error != 0) {
@@ -251,6 +265,7 @@ mmap_at(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
for (int i = 0; i < npgs; ++i) {
pg = vm_pagealloc(map_obj, PALLOC_ZERO);
+ page_off = i * DEFAULT_PAGESIZE;
if (pg == NULL) {
/* TODO */
@@ -258,8 +273,14 @@ mmap_at(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
return NULL;
}
+ /* TODO: copy-on-write */
+ if (addr == NULL) {
+ va = pg->phys_addr;
+ addr = (void *)va;
+ }
+
pa = pg->phys_addr;
- error = vm_map(vas, va, pa, prot, len);
+ error = vm_map(vas, va + page_off, pa, prot, len);
if (error < 0) {
pr_error("mmap: failed to map page (retval=%x)\n", error);
return NULL;
@@ -292,7 +313,7 @@ done:
* multiple of the machine page size.
*/
int
-munmap_at(void *addr, size_t len)
+munmap(void *addr, size_t len)
{
int pgno;
vaddr_t va;
@@ -348,7 +369,7 @@ munmap_at(void *addr, size_t len)
* arg5 -> off
*/
scret_t
-mmap(struct syscall_args *scargs)
+sys_mmap(struct syscall_args *scargs)
{
void *addr;
size_t len;
@@ -357,11 +378,11 @@ mmap(struct syscall_args *scargs)
addr = (void *)scargs->arg0;
len = scargs->arg1;
- prot = scargs->arg2;
+ prot = scargs->arg2 | PROT_USER;
flags = scargs->arg3;
fildes = scargs->arg4;
off = scargs->arg5;
- return (scret_t)mmap_at(addr, len, prot, flags, fildes, off);
+ return (scret_t)mmap(addr, len, prot, flags, fildes, off);
}
/*
@@ -371,14 +392,14 @@ mmap(struct syscall_args *scargs)
* arg1 -> len
*/
scret_t
-munmap(struct syscall_args *scargs)
+sys_munmap(struct syscall_args *scargs)
{
void *addr;
size_t len;
addr = (void *)scargs->arg0;
len = scargs->arg1;
- return (scret_t)munmap_at(addr, len);
+ return (scret_t)munmap(addr, len);
}
/*