summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/init_main.c113
-rw-r--r--sys/kern/kern_cpu.c76
-rw-r--r--sys/kern/kern_device.c84
-rw-r--r--sys/kern/kern_exec.c240
-rw-r--r--sys/kern/kern_filedesc.c494
-rw-r--r--sys/kern/kern_intr.c127
-rw-r--r--sys/kern/kern_ioctl.c72
-rw-r--r--sys/kern/kern_loader.c220
-rw-r--r--sys/kern/kern_mutex.c52
-rw-r--r--sys/kern/kern_panic.c63
-rw-r--r--sys/kern/kern_reboot.c51
-rw-r--r--sys/kern/kern_sched.c490
-rw-r--r--sys/kern/kern_signal.c102
-rw-r--r--sys/kern/kern_subr.c134
-rw-r--r--sys/kern/kern_syscall.c54
-rw-r--r--sys/kern/kern_syslog.c168
-rw-r--r--sys/kern/kern_timer.c112
-rw-r--r--sys/kern/kern_tty.c304
-rw-r--r--sys/kern/vfs_init.c89
-rw-r--r--sys/kern/vfs_lookup.c182
-rw-r--r--sys/kern/vfs_mount.c217
-rw-r--r--sys/kern/vfs_subr.c258
22 files changed, 0 insertions, 3702 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
deleted file mode 100644
index 847f4a6..0000000
--- a/sys/kern/init_main.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/cdefs.h>
-#include <sys/syslog.h>
-#include <sys/machdep.h>
-#include <sys/timer.h>
-#include <sys/sched.h>
-#include <sys/tty.h>
-#include <sys/vfs.h>
-#include <sys/driver.h>
-#include <machine/cpu_mp.h>
-#include <firmware/acpi/acpi.h>
-#include <vm/physseg.h>
-#include <logo.h>
-
-__MODULE_NAME("init_main");
-__KERNEL_META("$Hyra$: init_main.c, Ian Marco Moffett, "
- "Where the Hyra kernel first starts up");
-
-static inline void
-log_timer(const char *purpose, tmrr_status_t s, const struct timer *tmr)
-{
- if (s == TMRR_EMPTY_ENTRY) {
- kprintf("init_main: %s not yet registered\n", purpose);
- } else if (tmr->name == NULL) {
- kprintf("init_main: Nameless %s registered; unknown\n", purpose);
- } else {
- kprintf("init_main: %s registered: %s\n", purpose, tmr->name);
- }
-}
-
-/*
- * Logs what timers are registered
- * on the system.
- */
-static void
-list_timers(void)
-{
- struct timer timer_tmp;
- tmrr_status_t status;
-
- status = req_timer(TIMER_SCHED, &timer_tmp);
- log_timer("SCHED_TMR", status, &timer_tmp);
-
- status = req_timer(TIMER_GP, &timer_tmp);
- log_timer("GENERAL_PURPOSE_TMR", status, &timer_tmp);
-}
-
-void
-main(void)
-{
- struct cpu_info *ci;
- int status;
-
- __TRY_CALL(pre_init);
- syslog_init();
- PRINT_LOGO();
-
- kprintf("Hyra/%s v%s: %s (%s)\n",
- HYRA_ARCH, HYRA_VERSION, HYRA_BUILDDATE,
- HYRA_BUILDBRANCH);
-
- acpi_init();
- __TRY_CALL(chips_init);
-
- processor_init();
- list_timers();
- vfs_init();
-
- /* Attach the root TTY */
- if ((status = tty_attach(&g_root_tty)) < 0)
- kprintf("Failed to attach root TTY (got %d)\n", status);
-
- DRIVERS_INIT();
- sched_init();
- ci = this_cpu();
-
- /* Stop writing kernel messages to TTY */
- g_syslog_use_tty = false;
-
- __TRY_CALL(ap_bootstrap, ci);
- sched_enter();
-
- while (1);
- __builtin_unreachable();
-}
diff --git a/sys/kern/kern_cpu.c b/sys/kern/kern_cpu.c
deleted file mode 100644
index 1779244..0000000
--- a/sys/kern/kern_cpu.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/cpu.h>
-#include <sys/types.h>
-#include <sys/panic.h>
-#include <sys/machdep.h>
-#include <vm/dynalloc.h>
-#include <assert.h>
-
-__MODULE_NAME("kern_cpu");
-__KERNEL_META("$Hyra$: kern_cpu.c, Ian Marco Moffett, "
- "Machine independent CPU interface");
-
-#define CI_LIST_SZ \
- sizeof(struct cpu_info *) * (MAXCPUS + 1)
-
-static size_t ncpu = 0;
-static struct cpu_info **ci_list = NULL;
-
-void
-cpu_attach(struct cpu_info *ci)
-{
- if ((ci->idx = ncpu++) >= (MAXCPUS + 1)) {
- panic("Machine core count exceeds MAXCPUS!\n");
- }
-
- if (ci_list == NULL) {
- ci_list = dynalloc(CI_LIST_SZ);
- __assert(ci_list != NULL);
- }
-
- ci_list[cpu_index(ci)] = ci;
-}
-
-struct cpu_info *
-cpu_get(size_t i)
-{
- if (i >= ncpu || ci_list == NULL) {
- return NULL;
- }
-
- return ci_list[i];
-}
-
-size_t
-cpu_count(void)
-{
- return ncpu;
-}
diff --git a/sys/kern/kern_device.c b/sys/kern/kern_device.c
deleted file mode 100644
index cbba965..0000000
--- a/sys/kern/kern_device.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/device.h>
-#include <sys/queue.h>
-#include <sys/errno.h>
-#include <sys/types.h>
-#include <sys/spinlock.h>
-
-static TAILQ_HEAD(, device) devices;
-static struct spinlock devices_lock = {0};
-static bool device_list_init = false;
-
-dev_t
-device_alloc_major(void)
-{
- static dev_t major = 1;
- return major++;
-}
-
-struct device *
-device_fetch(dev_t major, dev_t minor)
-{
- struct device *dev;
-
- TAILQ_FOREACH(dev, &devices, link) {
- if (dev->major == major && dev->minor == minor) {
- return dev;
- }
- }
-
- return NULL;
-}
-
-dev_t
-device_create(struct device *dev, dev_t major, dev_t minor)
-{
- if (dev == NULL || minor == 0) {
- return -EINVAL;
- }
-
- if (major == 0) {
- return -EINVAL;
- }
-
- if (!device_list_init) {
- TAILQ_INIT(&devices);
- device_list_init = true;
- }
-
- dev->major = major;
- dev->minor = minor;
-
- spinlock_acquire(&devices_lock);
- TAILQ_INSERT_HEAD(&devices, dev, link);
- spinlock_release(&devices_lock);
- return dev->major;
-}
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
deleted file mode 100644
index 202da23..0000000
--- a/sys/kern/kern_exec.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/sched.h>
-#include <sys/system.h>
-#include <sys/errno.h>
-#include <sys/vfs.h>
-#include <sys/exec.h>
-#include <sys/filedesc.h>
-#include <sys/signal.h>
-#include <sys/loader.h>
-#include <sys/cdefs.h>
-#include <vm/dynalloc.h>
-#include <sys/syslog.h>
-#include <string.h>
-
-__MODULE_NAME("exec");
-__KERNEL_META("$Hyra$: kern_exec.c, Ian Marco Moffett, "
- "exec() implementation");
-
-#define ARG_MAX 1024
-
-/*
- * Allocates a buffer in in `res' and fetches
- * the args from `argv'
- *
- * @argv: User argv
- * @res: Exec args result.
- *
- * XXX: res->argp is dynamically allocated, remember
- * to free it!
- */
-static int
-exec_get_args(char **argv, struct exec_args *res)
-{
- static char *dmmy_envp[] = {NULL};
- const size_t ARG_LEN = sizeof(char) * ARG_MAX;
- char *argp = NULL;
- void *tmp;
-
- struct proc *td;
- size_t argp_len = 0;
-
- if (res == NULL)
- return -EINVAL;
-
- /* Allocate argp */
- res->argp = dynalloc(ARG_LEN);
- if (res->argp == NULL)
- return -ENOMEM;
-
- td = this_td();
- res->vas = td->addrsp;
- res->envp = dmmy_envp;
-
- /* Read argv */
- copyin((uintptr_t)argv, &argp, sizeof(char *));
- for (;;) {
- if (argp == NULL) {
- res->argp[argp_len] = NULL;
- break;
- }
-
- /* Fetch this arg and get next argp */
- copyinstr((uintptr_t)argp, res->argp[argp_len++], ARG_MAX);
- copyin((uintptr_t)++argv, &argp, sizeof(char *));
-
- /* Try to resize the argp buffer */
- tmp = dynrealloc(res->argp, ARG_LEN * (argp_len + 1));
- if (tmp == NULL) {
- dynfree(res->argp);
- return -ENOMEM;
- }
- res->argp = tmp;
- }
-
- return 0;
-}
-
-/*
- * Reset the stack of the process.
- *
- * @td: Target thread.
- * @args: Exec args.
- *
- * Returns the new stack pointer.
- */
-static uintptr_t
-exec_set_stack(struct proc *td, struct exec_args args)
-{
- struct vm_range *stack_range;
- uintptr_t stack_top, sp;
-
- stack_range = &td->addr_range[ADDR_RANGE_STACK];
- stack_top = stack_range->start + (PROC_STACK_SIZE);
-
- sp = loader_init_stack((void *)stack_top, args);
- return sp;
-}
-
-/*
- * execv() implementation.
- *
- * @pathname: Path of file to execute.
- * @argv: Args.
- * @sp_res: Pointer to new stack pointer
- */
-static int
-execv(char *pathname, char **argv, uintptr_t *sp_res)
-{
- char *bin = NULL;
- struct filedesc *filedes;
- struct vm_range *exec_range;
- struct exec_args args;
-
- struct proc *td = this_td();
- int fd, ret = 0;
- int status;
- size_t bin_size;
-
- if ((status = exec_get_args(argv, &args)) != 0)
- return status;
-
- spinlock_acquire(&td->lock);
- fd = open(pathname, O_RDONLY);
-
- if (fd < 0) {
- ret = -ENOENT;
- goto done;
- }
-
- filedes = fd_from_fdnum(td, fd);
- if (__unlikely(filedes == NULL)) {
- /*
- * Should not happen. The kernel might be in some
- * erroneous state.
- */
- ret = -EIO;
- goto done;
- }
-
- lseek(fd, 0, SEEK_END);
- bin_size = filedes->offset;
- lseek(fd, 0, SEEK_SET);
-
- /* Allocate memory for the binary */
- bin = dynalloc(bin_size);
- if (bin == NULL) {
- ret = -ENOMEM;
- goto done;
- }
-
- /* Read-in the binary */
- if ((status = read(fd, bin, bin_size)) < 0) {
- ret = status;
- goto done;
- }
-
- /*
- * Unload the current process image. After we do this,
- * we cannot return in this state until we replace it.
- *
- * XXX: This is one of the last things we do in case of
- * errors.
- */
- exec_range = &td->addr_range[ADDR_RANGE_EXEC];
- loader_unload(td->addrsp, exec_range);
-
- /*
- * Now we try to load the new program and hope everything
- * works... If something goes wrong here then we'll be forced
- * to send a SIGSEGV to the thread.
- */
- status = loader_load(td->addrsp, bin, &args.auxv, 0, NULL, exec_range);
- if (status != 0) {
- /* Well shit */
- kprintf("exec: Failed to load new process image\n");
- signal_raise(td, SIGSEGV);
- for (;;);
- }
-
- *sp_res = exec_set_stack(td, args);
- set_frame_ip(td->tf, args.auxv.at_entry);
-done:
- /* We are done, cleanup and release the thread */
- if (bin != NULL) dynfree(bin);
- fd_close_fdnum(td, fd);
- dynfree(args.argp);
- spinlock_release(&td->lock);
- return ret;
-}
-
-/*
- * Arg0: Pathname
- * Arg1: Argv
- */
-uint64_t
-sys_execv(struct syscall_args *args)
-{
- uintptr_t sp;
- char pathname[PATH_MAX];
- char **argv = (char **)args->arg1;
-
- int status;
- struct proc *td = this_td();
-
- copyinstr(args->arg0, pathname, PATH_MAX);
- if ((status = execv(pathname, argv, &sp)) != 0)
- return status;
-
- args->ip = get_frame_ip(td->tf);
- args->sp = sp;
- return 0;
-}
diff --git a/sys/kern/kern_filedesc.c b/sys/kern/kern_filedesc.c
deleted file mode 100644
index 17a3d84..0000000
--- a/sys/kern/kern_filedesc.c
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/filedesc.h>
-#include <sys/proc.h>
-#include <sys/sio.h>
-#include <sys/sched.h>
-#include <sys/errno.h>
-#include <sys/system.h>
-#include <sys/syslog.h>
-#include <sys/vfs.h>
-#include <sys/signal.h>
-#include <sys/vnode.h>
-#include <vm/dynalloc.h>
-#include <dev/vcons/vcons.h>
-#include <assert.h>
-#include <string.h>
-
-#define MAX_RW_SIZE 0x7FFFF000
-
-/*
- * This function is a helper for write(). It creates
- * a buffer and copies write data to it.
- *
- * @td: Current thread.
- * @data: Data to copy.
- * @buf_out: Pointer to buffer that will store data.
- * @count: Number of bytes.
- */
-static int
-make_write_buf(struct proc *td, const void *data, char **buf_out, size_t count)
-{
- char *buf = NULL;
-
- /* Count cannot be 0 or exceed the max size */
- if (count > MAX_RW_SIZE || count == 0) {
- return -EINVAL;
- }
-
- buf = dynalloc(count);
-
- if (buf == NULL) {
- return -ENOMEM;
- }
-
- __assert(buf_out != NULL);
- *buf_out = buf;
-
- memset(buf, 0, count);
-
- if (td->is_user) {
- /*
- * A user process called us, so we want to be careful
- * and use copyin()
- */
- if (copyin((uintptr_t)data, buf, count) != 0) {
- signal_raise(NULL, SIGSEGV);
- }
- } else {
- /* Can just memcpy() here */
- memcpy(buf, (char *)data, count);
- }
-
- return 0;
-}
-
-/*
- * Helper function for write()
- */
-static ssize_t
-do_write(struct vnode *vp, char *buf, size_t count)
-{
- struct sio_txn sio = { .buf = buf, .len = count };
- struct vops *vops = vp->vops;
- int status;
-
- __assert(vops != NULL);
-
- /* Can we call the write operation? */
- if (vops->write == NULL) {
- return -EACCES;
- }
-
- /* Attempt a write */
- if ((status = vops->write(vp, &sio)) < 0) {
- return status;
- }
-
- return count;
-}
-
-/*
- * Allocate a file descriptor.
- *
- * @td: Thread to allocate from, NULL for current thread.
- * @fd_out: Pointer to allocated file descriptor output.
- *
- * This routine will create a new file descriptor
- * table entry.
- *
- * Returns 0 on success.
- */
-int
-fd_alloc(struct proc *td, struct filedesc **fd_out)
-{
- struct filedesc *fd;
-
- if (td == NULL) {
- td = this_td();
- __assert(td != NULL);
- }
-
- /* Find free fd table entry */
- for (size_t i = 0; i < PROC_MAX_FDS; ++i) {
- if (td->fds[i] != NULL) {
- /* In use */
- continue;
- }
-
- fd = dynalloc(sizeof(struct filedesc));
- memset(fd, 0, sizeof(struct filedesc));
-
- if (fd == NULL) {
- return -ENOMEM;
- }
-
- fd->fdno = i;
- td->fds[i] = fd;
-
- if (fd_out != NULL)
- *fd_out = fd;
-
- return 0;
- }
-
- return -EMFILE;
-}
-
-/*
- * Fetch a file descriptor from a file descriptor
- * number.
- *
- * @td: Thread to fetch from, NULL for current thread.
- * @fdno: File descriptor to fetch
- */
-struct filedesc *
-fd_from_fdnum(const struct proc *td, int fdno)
-{
- if (td == NULL) {
- td = this_td();
- __assert(td != NULL);
- }
-
- if (fdno < 0 || fdno > PROC_MAX_FDS) {
- return NULL;
- }
-
- return td->fds[fdno];
-}
-
-/*
- * Close a file descriptor from its fd number.
- *
- * @td: Thread to fetch from, NULL for current thread.
- * @fdno: File descriptor number to close.
- */
-void
-fd_close_fdnum(struct proc *td, int fdno)
-{
- struct filedesc *fd;
-
- if (td == NULL) {
- td = this_td();
- __assert(td != NULL);
- }
-
- fd = fd_from_fdnum(td, fdno);
- if (fd == NULL) {
- return;
- }
-
- if (fd->vnode != NULL) {
- vfs_close(fd->vnode);
- }
-
- dynfree(fd);
- td->fds[fdno] = NULL;
-}
-
-ssize_t
-write(int fd, const void *buf, size_t count)
-{
- struct proc *td = this_td();
- struct filedesc *desc = NULL;
- struct vnode *vp = NULL;
- char *in_buf = NULL;
-
- ssize_t ret = count;
- int status;
-
- /*
- * Create our write buffer... Memory will be allocated
- * and data copied.
- */
- if ((status = make_write_buf(td, buf, &in_buf, count)) != 0) {
- return status;
- }
-
- /* Is this stdout/stderr? */
- if (fd == 1 || fd == 2) {
- /* TODO: Update this when we have PTYs */
- vcons_putstr(&g_syslog_screen, in_buf, count);
- return count;
- }
-
- desc = fd_from_fdnum(td, fd);
- if (desc == NULL) {
- return -EBADF;
- }
-
- mutex_acquire(&desc->lock);
- if (desc->oflag != O_WRONLY && desc->oflag != O_WRONLY) {
- ret = -EACCES;
- goto cleanup;
- }
-
- /* Does this file descriptor exist? */
- if (desc == NULL) {
- ret = -EBADF;
- goto cleanup;
- }
-
- /* Do we have a vnode? */
- if (desc->vnode == NULL) {
- ret = -EACCES;
- goto cleanup;
- }
-
- vp = desc->vnode;
- status = do_write(vp, in_buf, count);
-
- if (status < 0) {
- ret = status;
- goto cleanup;
- }
-cleanup:
- mutex_release(&desc->lock);
- dynfree(in_buf);
- return ret;
-}
-
-/*
- * Open a file and return a file descriptor.
- *
- * @pathname: File path.
- * @oflag: Flags.
- */
-int
-open(const char *pathname, int oflag)
-{
- struct vnode *vp;
- struct filedesc *fd;
- int status;
-
- /*
- * Attempt to create a vnode, call the open hook then
- * allocate a file descriptor
- */
- if ((status = vfs_path_to_node(pathname, &vp)) != 0) {
- return status;
- }
- if ((status = vfs_open(vp)) != 0) {
- return status;
- }
- if ((status = fd_alloc(this_td(), &fd)) != 0) {
- return status;
- }
-
- fd->oflag = oflag;
- fd->vnode = vp;
- fd->is_dir = (vp->type == VDIR);
- return fd->fdno;
-}
-
-/*
- * Read file into a buffer.
- *
- * @fd: File descriptor number.
- * @buf: Buffer to read to.
- * @count: Number of bytes to read.
- */
-int
-read(int fd, void *buf, size_t count)
-{
- ssize_t bytes_read;
- struct vnode *vnode;
- struct filedesc *fd_desc;
- struct sio_txn sio = {
- .buf = buf,
- .len = count,
- .type = SIO_NONE
- };
-
- fd_desc = fd_from_fdnum(this_td(), fd);
- if (fd_desc == NULL) {
- return -EBADF;
- }
-
- mutex_acquire(&fd_desc->lock);
- if (fd_desc->oflag == O_WRONLY) {
- bytes_read = -EACCES;
- goto done;
- }
-
- sio.offset = fd_desc->offset;
- vnode = fd_desc->vnode;
-
- if (count > MAX_RW_SIZE) {
- bytes_read = -EACCES;
- goto done;
- }
-
- bytes_read = vfs_read(vnode, &sio);
- fd_desc->offset += bytes_read;
-done:
- mutex_release(&fd_desc->lock);
- return bytes_read;
-}
-
-/*
- * Reposition the file offset
- *
- * @fd: File descriptor.
- * @offset: Offset for the reposition
- * @whence: SEEK_SET, SEEK_CUR, or SEEK_END
- *
- * TODO: Implement SEEK_END
- */
-off_t
-lseek(int fd, off_t offset, int whence)
-{
- struct filedesc *fd_desc;
- struct vattr vattr;
-
- fd_desc = fd_from_fdnum(this_td(), fd);
-
- if (fd_desc == NULL) {
- return -EBADF;
- }
-
- if (vfs_getattr(fd_desc->vnode, &vattr) != 0) {
- return -1;
- }
-
- switch (whence) {
- case SEEK_SET:
- if (offset > vattr.size)
- return -ESPIPE;
-
- fd_desc->offset = offset;
- break;
- case SEEK_CUR:
- if ((fd_desc->offset + offset) > vattr.size)
- return -ESPIPE;
-
- fd_desc->offset += offset;
- break;
- case SEEK_END:
- fd_desc->offset = vattr.size;
- break;
- default:
- return -EINVAL;
- }
-
- return fd_desc->offset;
-}
-
-/*
- * arg0: int fd
- * arg1: const void *buf
- * arg2: count
- */
-uint64_t
-sys_write(struct syscall_args *args)
-{
- return write(args->arg0, (void *)args->arg1, args->arg2);
-}
-
-/*
- * arg0: const char *pathname
- * arg1: int oflag
- */
-uint64_t
-sys_open(struct syscall_args *args)
-{
- char *pathbuf = dynalloc(sizeof(char) * PATH_MAX);
- int ret;
-
- if (pathbuf == NULL) {
- return -ENOMEM;
- }
-
- if (copyinstr(args->arg0, pathbuf, PATH_MAX) != 0) {
- signal_raise(NULL, SIGSEGV);
- }
-
- ret = open(pathbuf, args->arg1);
- dynfree(pathbuf);
- return ret;
-}
-
-/*
- * arg0: fd
- */
-uint64_t
-sys_close(struct syscall_args *args)
-{
- fd_close_fdnum(this_td(), args->arg0);
- return 0;
-}
-
-/*
- * arg0: fd
- * arg1: char *buf
- * arg2: size_t count
- */
-uint64_t
-sys_read(struct syscall_args *args)
-{
- char *kbuf;
- ssize_t bytes_read;
-
- if (args->arg2 > MAX_RW_SIZE || args->arg2 == 0) {
- return -EINVAL;
- }
-
- kbuf = dynalloc(args->arg2);
- if (kbuf == NULL) {
- return -ENOMEM;
- }
-
- /*
- * Try to read into our kernel buffer then copy out
- * to userspace.
- */
- if ((bytes_read = read(args->arg0, kbuf, args->arg2)) < 0) {
- /* Failure */
- dynfree(kbuf);
- return bytes_read;
- }
- if (copyout(kbuf, args->arg1, bytes_read) != 0) {
- signal_raise(NULL, SIGSEGV);
- }
-
- dynfree(kbuf);
- return bytes_read;
-}
-
-/*
- * arg0: fd
- * arg1: offset:
- * arg2: whence
- */
-uint64_t
-sys_lseek(struct syscall_args *args)
-{
- return lseek(args->arg0, args->arg1, args->arg2);
-}
diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c
deleted file mode 100644
index 0c80334..0000000
--- a/sys/kern/kern_intr.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/intr.h>
-#include <sys/queue.h>
-#include <sys/mutex.h>
-#include <vm/dynalloc.h>
-#include <fs/procfs.h>
-#include <string.h>
-#include <assert.h>
-
-#define PROC_BUF_SIZE 4096
-
-static TAILQ_HEAD(, intr_info) intrlist;
-static struct mutex intrlist_lock = {0};
-static struct proc_entry *proc;
-
-static int
-proc_read(struct proc_entry *entry, struct sio_txn *sio)
-{
- struct intr_info *info;
- char buf[PROC_BUF_SIZE];
- char *p = &buf[0];
- size_t idx = 0, len;
- int res;
-
- mutex_acquire(&intrlist_lock);
- TAILQ_FOREACH(info, &intrlist, link) {
- __assert((sizeof(buf) - idx) > 0);
- res = snprintf(p, sizeof(buf) - idx,
- "CPU%d\t\t%d\t\t%s\t\t%s\n",
- info->affinity,
- info->count,
- info->source,
- info->device
- );
-
- if (res > 0) {
- idx += res;
- p += res;
- }
-
- if (idx >= (PROC_BUF_SIZE - 1)) {
- break;
- }
- }
-
- len = idx + 1;
- buf[idx] = '\0';
-
- if (sio->len > PROC_BUF_SIZE)
- sio->len = PROC_BUF_SIZE;
- if (len > sio->len)
- len = sio->len;
-
- memcpy(sio->buf, buf, len);
- mutex_release(&intrlist_lock);
- return len;
-}
-
-/*
- * Register an interrupt stat
- *
- * @source: Source of interrupt (e.g IOAPIC)
- * @dev: Device (e.g i8042)
- */
-struct intr_info *
-intr_info_alloc(const char *source, const char *dev)
-{
- struct intr_info *intr;
-
- intr = dynalloc(sizeof(*intr));
- if (intr == NULL)
- return NULL;
-
- memset(intr, 0, sizeof(*intr));
- intr->source = source;
- intr->device = dev;
- return intr;
-}
-
-void
-intr_register(struct intr_info *info)
-{
- if (info == NULL)
- return;
-
- TAILQ_INSERT_TAIL(&intrlist, info, link);
-}
-
-void
-intr_init_proc(void)
-{
- /* Init the interrupt list */
- TAILQ_INIT(&intrlist);
-
- /* Setup /proc/interrupts */
- proc = procfs_alloc_entry();
- proc->read = proc_read;
- procfs_add_entry("interrupts", proc);
-}
diff --git a/sys/kern/kern_ioctl.c b/sys/kern/kern_ioctl.c
deleted file mode 100644
index 4b81983..0000000
--- a/sys/kern/kern_ioctl.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/system.h>
-#include <sys/vnode.h>
-#include <sys/filedesc.h>
-#include <sys/syscall.h>
-#include <sys/errno.h>
-#include <sys/sched.h>
-#include <fs/devfs.h>
-
-static int
-do_ioctl(int fd, uint32_t cmd, uintptr_t arg)
-{
- struct proc *td = this_td();
- struct filedesc *filedes;
- struct vnode *vp;
- struct device *dev;
- int status;
-
- filedes = fd_from_fdnum(td, fd);
-
- /* Fetch the vnode */
- if (filedes == NULL)
- return -EBADF;
- if ((vp = filedes->vnode) == NULL)
- return -EIO;
-
- if ((status = devfs_get_dev(vp, &dev)) != 0)
- return status;
- if (dev->ioctl == NULL)
- return -EIO;
-
- return dev->ioctl(dev, cmd, arg);
-}
-
-/*
- * Arg0: Fd.
- * Arg1: Cmd.
- * Arg2: Arg.
- */
-uint64_t
-sys_ioctl(struct syscall_args *args)
-{
- return do_ioctl(args->arg0, args->arg1, args->arg2);
-}
diff --git a/sys/kern/kern_loader.c b/sys/kern/kern_loader.c
deleted file mode 100644
index 8edc160..0000000
--- a/sys/kern/kern_loader.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/loader.h>
-#include <sys/cdefs.h>
-#include <sys/elf.h>
-#include <sys/types.h>
-#include <sys/syslog.h>
-#include <sys/errno.h>
-#include <sys/proc.h>
-#include <vm/vm.h>
-#include <vm/map.h>
-#include <vm/physseg.h>
-#include <vm/dynalloc.h>
-#include <string.h>
-#include <assert.h>
-
-__MODULE_NAME("kern_loader");
-__KERNEL_META("$Hyra$: kern_loader.c, Ian Marco Moffett, "
- "Kernel ELF loader");
-
-#define pr_trace(fmt, ...) kprintf("loader: " fmt, ##__VA_ARGS__)
-#define pr_error(...) pr_trace(__VA_ARGS__)
-
-#define PHDR(hdrptr, IDX) \
- (void *)((uintptr_t)hdr + (hdrptr)->e_phoff + (hdrptr->e_phentsize*IDX))
-
-int
-loader_unload(struct vas vas, struct vm_range *exec_range)
-{
- size_t start, end;
-
- start = exec_range->start;
- end = exec_range->end;
-
- /* FIXME: Figure out how to free physical memory too */
- return vm_map_destroy(vas, start, (end - start));
-}
-
-uintptr_t
-loader_init_stack(void *stack_top, struct exec_args args)
-{
- uintptr_t *sp = stack_top;
- uintptr_t old_sp = 0;
- size_t argc, envc, len;
- char **argvp = args.argp;
- char **envp = args.envp;
- struct auxval auxv = args.auxv;
-
- /* Copy strings */
- old_sp = (uintptr_t)sp;
- for (argc = 0; argvp[argc] != NULL; ++argc) {
- len = strlen(argvp[argc]) + 1;
- sp = (void *)((char *)sp - len);
- memcpy((char *)sp, argvp[argc], len);
- }
- for (envc = 0; envp[envc] != NULL; ++envc) {
- len = strlen(envp[envc]) + 1;
- sp = (void *)((char *)sp - len);
- memcpy((char *)sp, envp[envc], len);
- }
-
- /* Ensure the stack is aligned */
- sp = (void *)__ALIGN_DOWN((uintptr_t)sp, 16);
- if (((argc + envc + 1) & 1) != 0)
- --sp;
-
- AUXVAL(sp, AT_NULL, 0x0);
- AUXVAL(sp, AT_SECURE, 0x0);
- AUXVAL(sp, AT_ENTRY, auxv.at_entry);
- AUXVAL(sp, AT_PHDR, auxv.at_phdr);
- AUXVAL(sp, AT_PHNUM, auxv.at_phnum);
- AUXVAL(sp, AT_PAGESIZE, vm_get_page_size());
- STACK_PUSH(sp, 0);
-
- /* Copy envp pointers */
- sp -= envc;
- for (int i = 0; i < envc; ++i) {
- len = strlen(envp[i]) + 1;
- old_sp -= len;
- sp[i] = KERN_TO_USER(old_sp);
- }
-
- /* Copy argvp pointers */
- STACK_PUSH(sp, 0);
- sp -= argc;
- for (int i = 0; i < argc; ++i) {
- len = strlen(argvp[i]) + 1;
- old_sp -= len;
- sp[i] = KERN_TO_USER(old_sp);
- }
-
- STACK_PUSH(sp, argc);
- return (uintptr_t)sp;
-}
-
-int loader_load(struct vas vas, const void *dataptr, struct auxval *auxv,
- size_t load_base, char **ld_path, struct vm_range *prog_range)
-{
- const Elf64_Ehdr *hdr = dataptr;
- Elf64_Phdr *phdr;
- vm_prot_t prot = PROT_USER;
-
- uintptr_t physmem;
- size_t misalign, page_count, map_len;
- int status;
-
- uintptr_t start_addr = (uintptr_t)-1;
- uintptr_t end_addr = 0;
-
- const size_t GRANULE = vm_get_page_size();
- void *tmp_ptr;
-
- if (auxv == NULL) {
- pr_error("Auxval argument NULL\n");
- return -1;
- }
-
- if (memcmp(hdr->e_ident, ELFMAG, 4) != 0) {
- /* Bad ELF header */
- pr_error("ELF header bad! (Magic incorrect)\n");
- return -1;
- }
-
- /* Parse program headers */
- for (size_t i = 0; i < hdr->e_phnum; ++i) {
- phdr = PHDR(hdr, i);
- switch (phdr->p_type) {
- case PT_LOAD:
- if (__TEST(phdr->p_flags, PF_W))
- prot |= PROT_WRITE;
- if (__TEST(phdr->p_flags, PF_X)) {
- prot |= PROT_EXEC;
- }
-
- misalign = phdr->p_vaddr & (GRANULE - 1);
- page_count = __DIV_ROUNDUP(phdr->p_memsz + misalign, GRANULE);
- physmem = vm_alloc_pageframe(page_count);
- map_len = page_count * GRANULE;
-
- /*
- * Now we want to compute the start address of the
- * program and the end address.
- */
- if (start_addr == (uintptr_t)-1) {
- start_addr = phdr->p_vaddr;
- }
-
- end_addr = __MAX(end_addr, phdr->p_vaddr + page_count*GRANULE);
-
- /* Do we not have enough page frames? */
- if (physmem == 0) {
- pr_error("Failed to allocate physical memory\n");
- vm_free_pageframe(physmem, page_count);
- return -ENOMEM;
- }
-
- status = vm_map_create(vas, phdr->p_vaddr + load_base, physmem, prot, map_len);
-
- if (status != 0) {
- return status;
- }
-
- /* Now we want to copy the data */
- tmp_ptr = (void *)((uintptr_t)hdr + phdr->p_offset);
- memcpy(PHYS_TO_VIRT(physmem), tmp_ptr, phdr->p_filesz);
- break;
- case PT_INTERP:
- if (ld_path == NULL) {
- break;
- }
-
- *ld_path = dynalloc(phdr->p_filesz);
-
- if (ld_path == NULL) {
- pr_error("Failed to allocate memory for PT_INTERP path\n");
- return -ENOMEM;
- }
-
- memcpy(*ld_path, (char *)hdr + phdr->p_offset, phdr->p_filesz);
- break;
- case PT_PHDR:
- auxv->at_phdr = phdr->p_vaddr + load_base;
- break;
- }
- }
-
- auxv->at_entry = hdr->e_entry + load_base;
- auxv->at_phent = hdr->e_phentsize;
- auxv->at_phnum = hdr->e_phnum;
- prog_range->start = start_addr;
- prog_range->end = end_addr;
- return 0;
-}
diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c
deleted file mode 100644
index ea770b1..0000000
--- a/sys/kern/kern_mutex.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/mutex.h>
-#include <sys/sched.h>
-#include <sys/proc.h>
-
-void
-mutex_acquire(struct mutex *mutex)
-{
- struct proc *td = this_td();
- register bool rest = (td != NULL);
-
- while (__atomic_test_and_set(&mutex->lock, __ATOMIC_ACQUIRE)) {
- if (!rest)
- continue;
-
- sched_rest();
- }
-}
-
-void
-mutex_release(struct mutex *mutex)
-{
- __atomic_clear(&mutex->lock, __ATOMIC_RELEASE);
-}
diff --git a/sys/kern/kern_panic.c b/sys/kern/kern_panic.c
deleted file mode 100644
index 71744af..0000000
--- a/sys/kern/kern_panic.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/panic.h>
-#include <sys/syslog.h>
-#include <sys/machdep.h>
-#include <sys/spinlock.h>
-
-/*
- * Tells the user something terribly
- * wrong happened then halting the system
- * as soon as possible.
- *
- * XXX: There is no need to cleanup stuff here (e.g `va_list ap`)
- * as we won't be returning from here anyways and the source
- * of the panic could be *anywhere* so it's best not to mess with
- * things.
- */
-void
-panic(const char *fmt, ...)
-{
- va_list ap;
- static struct spinlock lock = {0};
-
- intr_mask();
- spinlock_acquire(&lock); /* Never released */
- __TRY_CALL(cpu_halt_others);
-
- g_syslog_use_tty = true;
- va_start(ap, fmt);
-
- kprintf(OMIT_TIMESTAMP "panic: ");
- vkprintf(fmt, &ap);
-
- machine_panic();
- __builtin_unreachable();
-}
diff --git a/sys/kern/kern_reboot.c b/sys/kern/kern_reboot.c
deleted file mode 100644
index 8f7c400..0000000
--- a/sys/kern/kern_reboot.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/reboot.h>
-#include <sys/panic.h>
-#include <sys/cdefs.h>
-#include <sys/machdep.h>
-
-int
-reboot(int type)
-{
- __TRY_CALL(cpu_reset);
-
- /* Should be unreachable if the reboot works */
- return -1;
-}
-
-/*
- * Arg0: Type
- */
-uint64_t
-sys_reboot(struct syscall_args *args)
-{
- return reboot(args->arg0);
-}
diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c
deleted file mode 100644
index ddc99ca..0000000
--- a/sys/kern/kern_sched.c
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/sched.h>
-#include <sys/schedvar.h>
-#include <sys/machdep.h>
-#include <sys/loader.h>
-#include <sys/errno.h>
-#include <sys/cdefs.h>
-#include <sys/filedesc.h>
-#include <sys/timer.h>
-#include <sys/panic.h>
-#include <sys/signal.h>
-#include <fs/initramfs.h>
-#include <vm/dynalloc.h>
-#include <vm/physseg.h>
-#include <vm/map.h>
-#include <vm/pmap.h>
-#include <string.h>
-#include <assert.h>
-
-/*
- * Thread ready queues - all threads ready to be
- * scheduled should be added to the toplevel queue.
- */
-static struct sched_queue qlist[SCHED_NQUEUE];
-
-/*
- * Global scheduler state.
- */
-static size_t nthread = 0;
-static schedpolicy_t policy = SCHED_POLICY_MLFQ;
-
-/*
- * Thread queue lock - all operations to `qlist'
- * must be done with this lock acquired.
- *
- * This lock is aligned on a cache line boundary to ensure
- * it has its own cache line to reduce contention. This is
- * because it is constantly acquired and released on every
- * processor.
- */
-__cacheline_aligned
-static struct spinlock tdq_lock = {0};
-
-/*
- * Lower thread priority.
- */
-static inline void
-td_pri_lower(struct proc *td)
-{
- if (td->priority < (SCHED_NQUEUE - 1))
- ++td->priority;
-}
-
-/*
- * Raise thread priority.
- */
-static inline void
-td_pri_raise(struct proc *td)
-{
- if (td->priority > 0)
- --td->priority;
-}
-
-/*
- * Called during preemption. We raise the priority
- * if the thread has been rested. If the thread has not
- * been rested, we lower its priority.
- */
-static void
-td_pri_update(struct proc *td)
-{
- if (td->rested) {
- td->rested = 0;
- td_pri_raise(td);
- return;
- }
-
- td_pri_lower(td);
-}
-
-/*
- * Enqueue a thread into the scheduler.
- */
-static void
-sched_enqueue_td(struct proc *td)
-{
- struct sched_queue *queue;
-
- spinlock_acquire(&tdq_lock);
- queue = &qlist[td->priority];
-
- TAILQ_INSERT_TAIL(&queue->q, td, link);
- spinlock_release(&tdq_lock);
-}
-
-/*
- * Dequeue a thread from a queue.
- */
-static struct proc *
-sched_dequeue_td(void)
-{
- struct sched_queue *queue;
- struct proc *td = NULL;
-
- spinlock_acquire(&tdq_lock);
-
- /*
- * Try to pop a thread from a queue. We start at the
- * highest priority which is 0.
- */
- for (size_t i = 0; i < SCHED_NQUEUE; ++i) {
- queue = &qlist[i];
-
- if (!TAILQ_EMPTY(&queue->q)) {
- td = TAILQ_FIRST(&queue->q);
- TAILQ_REMOVE(&queue->q, td, link);
- break;
- }
- }
-
- spinlock_release(&tdq_lock);
- return td;
-}
-
-/*
- * Create a new thread stack.
- * sched_new_td() helper.
- */
-static uintptr_t
-sched_create_stack(bool is_user, struct exec_args args, struct proc *td)
-{
- int status;
- uintptr_t stack;
- struct vm_range *stack_range;
- const vm_prot_t USERSTACK_PROT = PROT_WRITE | PROT_USER;
-
- stack_range = &td->addr_range[ADDR_RANGE_STACK];
-
- /*
- * Kernel stacks can be allocated with dynalloc() as they
- * are on the higher half.
- */
- if (!is_user) {
- stack = (uintptr_t)dynalloc(PROC_STACK_SIZE);
- stack_range->start = stack;
- stack_range->end = stack + PROC_STACK_SIZE;
- return loader_init_stack((void *)(stack + PROC_STACK_SIZE), args);
- }
-
- stack = vm_alloc_pageframe(PROC_STACK_PAGES);
- if (stack == 0) {
- return 0;
- }
-
- status = vm_map_create(args.vas, stack, stack, USERSTACK_PROT, PROC_STACK_SIZE);
- if (status != 0) {
- vm_free_pageframe(stack, PROC_STACK_PAGES);
- return 0;
- }
-
- stack_range->start = stack;
- stack_range->end = stack + PROC_STACK_SIZE;
-
- memset(USER_TO_KERN(stack), 0, PROC_STACK_SIZE);
- stack = loader_init_stack((void *)USER_TO_KERN(stack + PROC_STACK_SIZE), args);
- return stack;
-}
-
-/*
- * Create a new thread.
- *
- * @ip: Instruction pointer to start at.
- * @is_user: True for user program.
- * @exec_args: Common exec args.
- */
-static int
-sched_new_td(uintptr_t ip, bool is_user, struct exec_args args, struct vm_range *prog_range,
- struct proc **res)
-{
- struct vm_range *exec_range;
- struct proc *td;
- struct trapframe *tf;
- uintptr_t stack;
- int retval = 0;
-
- td = dynalloc(sizeof(struct proc));
- tf = dynalloc(sizeof(struct trapframe));
- if (td == NULL || tf == NULL) {
- retval = -ENOMEM;
- goto done;
- }
-
- /* Keep them in a known state */
- memset(td, 0, sizeof(*td));
- memset(tf, 0, sizeof(*tf));
-
- /* Try to create a stack */
- stack = sched_create_stack(is_user, args, td);
- if (stack == 0) {
- retval = -ENOMEM;
- goto done;
- }
-
- /* Setup initial thread state */
- td->pid = ++nthread;
- td->tf = tf;
- td->addrsp = args.vas;
- td->is_user = is_user;
- processor_init_pcb(td);
-
- /* Setup each mapping table */
- for (size_t i = 0; i < MTAB_ENTRIES; ++i) {
- TAILQ_INIT(&td->mapspace.mtab[i]);
- }
-
- /* Setup standard file descriptors */
- __assert(fd_alloc(td, NULL) == 0); /* STDIN */
- __assert(fd_alloc(td, NULL) == 0); /* STDOUT */
- __assert(fd_alloc(td, NULL) == 0); /* STDERR */
-
- exec_range = &td->addr_range[ADDR_RANGE_EXEC];
- memcpy(exec_range, prog_range, sizeof(struct vm_range));
-
- /* Init the trapframe */
- if (!is_user) {
- init_frame(tf, ip, stack);
- } else {
- init_frame_user(tf, ip, KERN_TO_USER(stack));
- }
-done:
- if (retval != 0 && td != NULL)
- dynfree(td);
- if (retval != 0 && tf != NULL)
- dynfree(td);
- if (retval == 0 && res != NULL)
- *res = td;
-
- return retval;
-}
-
-/*
- * Perform timer oneshot
- *
- * @now: True for shortest timeslice.
- */
-static inline void
-sched_oneshot(bool now)
-{
- struct timer timer;
- size_t usec = (now) ? SHORT_TIMESLICE_USEC : DEFAULT_TIMESLICE_USEC;
- tmrr_status_t tmr_status;
-
- tmr_status = req_timer(TIMER_SCHED, &timer);
- __assert(tmr_status == TMRR_SUCCESS);
-
- timer.oneshot_us(usec);
-}
-
-/*
- * Enter the schedulera and wait until
- * preemption.
- */
-void
-sched_enter(void)
-{
- sched_oneshot(false);
-
- for (;;) {
- hint_spinwait();
- }
-}
-
-/*
- * Initialize all of the queues.
- */
-static void
-sched_init_queues(void)
-{
- for (size_t i = 0; i < SCHED_NQUEUE; ++i) {
- TAILQ_INIT(&qlist[i].q);
- }
-}
-
-/*
- * Load the first thread (init)
- */
-static void
-sched_load_init(void)
-{
- struct exec_args args;
- struct proc *init;
- struct auxval *auxvp = &args.auxv;
- struct vm_range init_range;
- int tmp;
-
- char *argv[] = {"/usr/sbin/init", NULL};
- char *envp[] = {NULL};
- const char *init_bin;
-
- if ((init_bin = initramfs_open("/usr/sbin/init")) == NULL)
- panic("Could not open /usr/sbin/init\n");
-
- pmap_create_vas(vm_get_ctx(), &args.vas);
- args.argp = argv;
- args.envp = envp;
-
- tmp = loader_load(args.vas, init_bin, auxvp, 0, NULL, &init_range);
- if (tmp != 0)
- panic("Failed to load init\n");
-
- if (sched_new_td(auxvp->at_entry, true, args, &init_range, &init) != 0)
- panic("Failed to create init thread\n");
-
- sched_enqueue_td(init);
-}
-
-static void
-sched_destroy_td(struct proc *td)
-{
- struct vm_range *stack_range;
- struct vm_range *exec_range;
- vm_mapq_t *mapq;
-
- processor_free_pcb(td);
- stack_range = &td->addr_range[ADDR_RANGE_STACK];
- exec_range = &td->addr_range[ADDR_RANGE_EXEC];
-
- /*
- * User thread's have their stack allocated
- * with vm_alloc_pageframe() and kernel thread's
- * have their stacks allocated with dynalloc()
- */
- if (td->is_user) {
- vm_free_pageframe(stack_range->start, PROC_STACK_PAGES);
- } else {
- dynfree((void *)stack_range->start);
- }
-
- for (size_t i = 0; i < MTAB_ENTRIES; ++i) {
- mapq = &td->mapspace.mtab[i];
- vm_free_mapq(mapq);
- }
-
- for (size_t i = 0; i < PROC_MAX_FDS; ++i) {
- fd_close_fdnum(td, i);
- }
-
- loader_unload(td->addrsp, exec_range);
- pmap_free_vas(vm_get_ctx(), td->addrsp);
- dynfree(td);
-}
-
-/*
- * Cause an early preemption and lets
- * the next thread run.
- */
-void
-sched_rest(void)
-{
- struct proc *td = this_td();
-
- if (td == NULL)
- return;
-
- td->rested = 1;
- sched_oneshot(true);
-}
-
-void
-sched_exit(void)
-{
- struct proc *td = this_td();
- struct vas kvas = vm_get_kvas();
-
- spinlock_acquire(&tdq_lock);
- intr_mask();
-
- /* Switch to kernel VAS and destroy td */
- pmap_switch_vas(vm_get_ctx(), kvas);
- sched_destroy_td(td);
-
- spinlock_release(&tdq_lock);
- intr_unmask();
- sched_enter();
-}
-
-/*
- * Get the current running thread.
- */
-struct proc *
-this_td(void)
-{
- struct sched_state *state;
- struct cpu_info *ci;
-
- ci = this_cpu();
- state = &ci->sched_state;
- return state->td;
-}
-
-/*
- * Thread context switch routine
- *
- * Handles the transition from the currently running
- * thread to the next thread.
- */
-void
-sched_context_switch(struct trapframe *tf)
-{
- struct cpu_info *ci = this_cpu();
- struct sched_state *state = &ci->sched_state;
- struct proc *next_td, *td = state->td;
-
- if (td != NULL) {
- signal_handle(state->td);
- }
-
- /*
- * If a thread is currently running and our policy is
- * MLFQ, then we should update the thread's priority.
- */
- if (td != NULL && policy == SCHED_POLICY_MLFQ) {
- td_pri_update(td);
- }
-
- /* Don't preempt if we have no threads */
- if ((next_td = sched_dequeue_td()) == NULL) {
- sched_oneshot(false);
- return;
- }
-
- /*
- * If we have a thread currently running, then we should save
- * its current register state and re-enqueue it.
- */
- if (td != NULL) {
- memcpy(td->tf, tf, sizeof(struct trapframe));
- sched_enqueue_td(td);
- }
-
- /* Perform the switch */
- memcpy(tf, next_td->tf, sizeof(struct trapframe));
- processor_switch_to(td, next_td);
-
- state->td = next_td;
- pmap_switch_vas(vm_get_ctx(), next_td->addrsp);
- sched_oneshot(false);
-}
-
-uint64_t
-sys_exit(struct syscall_args *args)
-{
- sched_exit();
- __builtin_unreachable();
-}
-
-void
-sched_init(void)
-{
- sched_init_queues();
- sched_load_init();
-}
diff --git a/sys/kern/kern_signal.c b/sys/kern/kern_signal.c
deleted file mode 100644
index 7c31c86..0000000
--- a/sys/kern/kern_signal.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/proc.h>
-#include <sys/sched.h>
-#include <sys/cdefs.h>
-#include <sys/syslog.h>
-#include <sys/signal.h>
-#include <dev/vcons/vcons.h>
-#include <string.h>
-
-__MODULE_NAME("kern_signal");
-__KERNEL_META("$Hyra$: kern_signal.c, Ian Marco Moffett, "
- "Signal handling code");
-
-static void
-signal_log(const char *s)
-{
- vcons_putstr(&g_syslog_screen, s, strlen(s));
-}
-
-/*
- * Handle any signals within the current thread
- *
- * TODO: Add sigaction support, default action
- * for all currently is killing the process.
- */
-void
-signal_handle(struct proc *curtd)
-{
- int signo = curtd->signal;
-
- if (signo == 0) {
- return;
- }
-
- spinlock_acquire(&curtd->lock);
- curtd->signal = 0;
-
- switch (signo) {
- case SIGFPE:
- signal_log("Arithmetic error\n");
- break;
- case SIGSEGV:
- signal_log("Segmentation fault\n");
- break;
- case SIGKILL:
- signal_log("Killed\n");
- break;
- }
-
- spinlock_release(&curtd->lock);
- sched_exit();
-}
-
-/*
- * Raise a signal for a process
- *
- * @to: Can be NULL to mean the current process
- * @signal: Signal to send
- *
- * TODO: Add more functionality.
- */
-void
-signal_raise(struct proc *to, int signal)
-{
- if (to == NULL) {
- to = this_td();
- }
-
- to->signal = signal;
- if (to == this_td()) {
- /* Current process, just preempt */
- sched_context_switch(to->tf);
- }
-}
diff --git a/sys/kern/kern_subr.c b/sys/kern/kern_subr.c
deleted file mode 100644
index d9b1b3a..0000000
--- a/sys/kern/kern_subr.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/system.h>
-#include <sys/types.h>
-#include <sys/errno.h>
-#include <sys/sched.h>
-#include <vm/vm.h>
-#include <string.h>
-
-/*
- * Check if a user address is valid.
- *
- * @uaddr: User address to check.
- *
- * Returns true if valid, otherwise false.
- */
-static bool
-check_uaddr(uintptr_t uaddr)
-{
- struct proc *td = this_td();
- struct vm_range exec_range = td->addr_range[ADDR_RANGE_EXEC];
- struct vm_range stack_range = td->addr_range[ADDR_RANGE_STACK];
-
- if (uaddr >= exec_range.start && uaddr <= exec_range.end) {
- return true;
- }
- if (uaddr >= stack_range.start && uaddr <= stack_range.end) {
- return true;
- }
-
- return false;
-}
-
-/*
- * Copy from userspace to the kernel.
- *
- * @uaddr: Userspace address.
- * @kaddr: Kernelspace address.
- * @len: Length of data.
- */
-int
-copyin(uintptr_t uaddr, void *kaddr, size_t len)
-{
- if (!check_uaddr(uaddr) || !check_uaddr(uaddr + len)) {
- return -EFAULT;
- }
-
- memcpy(kaddr, (void *)uaddr, len);
- return 0;
-}
-
-/*
- * Copy from the kernel to userspace.
- *
- * @kaddr: Kernelspace address.
- * @uaddr: Userspace address.
- * @len: Length of data.
- */
-int
-copyout(const void *kaddr, uintptr_t uaddr, size_t len)
-{
- if (!check_uaddr(uaddr) || !check_uaddr(uaddr + len)) {
- return -EFAULT;
- }
-
- memcpy((void *)uaddr, kaddr, len);
- return 0;
-}
-
-/*
- * Copy in a string from userspace
- *
- * Unlike the typical copyin(), this routine will
- * copy until we've hit NUL ('\0')
- *
- * @uaddr: Userspace address.
- * @kaddr: Kernelspace address.
- * @len: Length of string.
- *
- * XXX: Please note that if `len' is less than the actual
- * string length, the returned value will not be
- * NUL terminated.
- */
-int
-copyinstr(uintptr_t uaddr, char *kaddr, size_t len)
-{
- char *dest = (char *)kaddr;
- char *src = (char *)uaddr;
-
- if (!check_uaddr(uaddr)) {
- return -EFAULT;
- }
-
- for (size_t i = 0; i < len; ++i) {
- if (!check_uaddr(uaddr + i)) {
- return -EFAULT;
- }
-
- dest[i] = src[i];
-
- if (src[i] == '\0') {
- break;
- }
- }
-
- return 0;
-}
diff --git a/sys/kern/kern_syscall.c b/sys/kern/kern_syscall.c
deleted file mode 100644
index 35185ea..0000000
--- a/sys/kern/kern_syscall.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/syscall.h>
-#include <sys/sched.h>
-#include <sys/cdefs.h>
-#include <sys/types.h>
-#include <sys/filedesc.h>
-#include <sys/system.h>
-#include <sys/exec.h>
-#include <sys/reboot.h>
-#include <sys/vfs.h>
-#include <vm/map.h>
-
-uint64_t(*g_syscall_table[__MAX_SYSCALLS])(struct syscall_args *args) = {
- sys_exit,
- sys_write,
- sys_open,
- sys_close,
- sys_read,
- sys_lseek,
- sys_mmap,
- sys_munmap,
- sys_ioctl,
- sys_execv,
- sys_mount,
- sys_reboot
-};
diff --git a/sys/kern/kern_syslog.c b/sys/kern/kern_syslog.c
deleted file mode 100644
index 86877e0..0000000
--- a/sys/kern/kern_syslog.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/syslog.h>
-#include <sys/machdep.h>
-#include <sys/tty.h>
-#include <sys/cdefs.h>
-#include <sys/timer.h>
-#include <sys/spinlock.h>
-#include <dev/vcons/vcons.h>
-#include <fs/procfs.h>
-#include <string.h>
-
-#if defined(__KMSG_BUF_SHIFT)
-#define KMSG_BUF_SHIFT __KMSG_BUF_SHIFT
-#else
-#define KMSG_BUF_SHIFT 12
-#endif
-
-#define KMSG_BUF_SIZE (1 << KMSG_BUF_SHIFT)
-
-__STATIC_ASSERT(KMSG_BUF_SHIFT <= 16, "Log buffer shift too large!\n");
-
-static char kmsg_buf[KMSG_BUF_SIZE];
-static size_t kmsg_buf_idx = 0;
-static struct proc_entry *kmsg_proc;
-static struct spinlock lock = {0};
-
-struct vcons_screen g_syslog_screen = {0};
-bool g_syslog_use_tty = true;
-
-static inline void
-kmsg_buf_putc(char c)
-{
- kmsg_buf[kmsg_buf_idx++] = c;
- kmsg_buf[kmsg_buf_idx] = '\0';
- if (kmsg_buf_idx >= (KMSG_BUF_SIZE - 1))
- kmsg_buf_idx = 0;
-}
-
-static int
-proc_kmsg_read(struct proc_entry *p, struct sio_txn *sio)
-{
- if (sio->len > KMSG_BUF_SIZE)
- sio->len = KMSG_BUF_SIZE;
-
- memcpy(sio->buf, kmsg_buf, sio->len);
- return sio->len;
-}
-
-static void
-syslog_write(const char *s, size_t len)
-{
- size_t tmp_len = len;
- const char *tmp_s = s;
-
- while (tmp_len--) {
-#if defined(__SERIAL_DEBUG)
- serial_dbgch(*tmp_s);
-#endif /* defined(__SERIAL_DEBUG) */
- kmsg_buf_putc(*tmp_s);
- if (g_syslog_use_tty)
- tty_putc(&g_root_tty, *tmp_s, TTY_SOURCE_RAW);
-
- ++tmp_s;
- }
-
- tty_flush(&g_root_tty);
-}
-
-/*
- * XXX: Not serialized
- */
-void
-vkprintf(const char *fmt, va_list *ap)
-{
- char buffer[1024] = {0};
-
- vsnprintf(buffer, sizeof(buffer), fmt, *ap);
- syslog_write(buffer, strlen(buffer));
-}
-
-void
-kprintf(const char *fmt, ...)
-{
- va_list ap;
- char timestamp[64] = "[ 0.000000] ";
- bool has_counter = true;
- bool use_timestamp = true;
- const char *fmt_p = fmt;
- struct timer tmr = {0};
-
- spinlock_acquire(&lock);
-
- /*
- * If the first char is OMIT_TIMESTAMP, then we won't
- * print out the timestamp.
- */
- if (*fmt_p == OMIT_TIMESTAMP[0]) {
- ++fmt_p;
- use_timestamp = false;
- }
-
- /* See if we can use the counter */
- if (req_timer(TIMER_GP, &tmr) != 0)
- has_counter = false;
-
- /* If we can use the counter, format the timestamp */
- if (has_counter) {
- if (tmr.get_time_sec != NULL && tmr.get_time_usec != NULL)
- snprintf(timestamp, sizeof(timestamp), "[ %d.%06d] ",
- tmr.get_time_sec(), tmr.get_time_usec());
-
- }
-
- if (use_timestamp) {
- syslog_write(timestamp, strlen(timestamp));
- }
-
- va_start(ap, fmt);
- vkprintf(fmt_p, &ap);
- va_end(ap);
-
- spinlock_release(&lock);
-}
-
-void
-syslog_init_proc(void)
-{
- kmsg_proc = procfs_alloc_entry();
- kmsg_proc->read = proc_kmsg_read;
- procfs_add_entry("kmsg", kmsg_proc);
-}
-
-void
-syslog_init(void)
-{
- g_syslog_screen.bg = 0x000000;
- g_syslog_screen.fg = 0x808080;
-
- vcons_attach(&g_syslog_screen);
-}
diff --git a/sys/kern/kern_timer.c b/sys/kern/kern_timer.c
deleted file mode 100644
index 5cc808f..0000000
--- a/sys/kern/kern_timer.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/timer.h>
-
-/*
- * When a timer on the machine has been registered
- * to the Hyra kernel, they'll be added to the Hyra timer
- * registry.
- */
-static const struct timer *tmr_registry[TIMER_ID_COUNT] = { 0 };
-
-/*
- * Returns true if the timer ID given
- * is valid.
- *
- * @id: ID to verify.
- */
-static inline bool
-is_timer_id_valid(timer_id_t id)
-{
- return id < TIMER_ID_COUNT;
-}
-
-/*
- * Adds timer on the machine to the timer registry. To be specific,
- * this function writes information about the specific timer to the
- * timer registry. However, it will not overwrite an entry. To do this
- * you must use tmr_registry_overwrite(), of course with caution.
- *
- * @id: ID of timer to register.
- * @tmr: Timer descriptor to register.
- */
-tmrr_status_t
-register_timer(timer_id_t id, const struct timer *tmr)
-{
- if (!is_timer_id_valid(id))
- return TMRR_INVALID_TYPE;
-
- if (tmr_registry[id] != NULL)
- return TMRR_HAS_ENTRY;
-
- tmr_registry[id] = tmr;
- return TMRR_SUCCESS;
-}
-
-/*
- * Overwrites an entry within the timer registery.
- * Use with caution.
- *
- * @id: ID of entry to overwrite.
- * @tmr: Timer descriptor to write.
- */
-tmrr_status_t
-tmr_registry_overwrite(timer_id_t id, const struct timer *tmr)
-{
- if (!is_timer_id_valid(id))
- return TMRR_INVALID_TYPE;
-
- tmr_registry[id] = tmr;
- return TMRR_SUCCESS;
-}
-
-/*
- * Requests a specific timer descriptor
- * with a specific ID.
- *
- * @id: ID to request.
- * @tmr_out: Pointer to memory that'll hold the
- * requested descriptor.
- */
-tmrr_status_t
-req_timer(timer_id_t id, struct timer *tmr_out)
-{
- if (!is_timer_id_valid(id))
- return TMRR_INVALID_TYPE;
-
- if (tmr_registry[id] == NULL)
- return TMRR_EMPTY_ENTRY;
-
- if (tmr_out == NULL)
- return TMRR_INVALID_ARG;
-
- *tmr_out = *tmr_registry[id];
- return TMRR_SUCCESS;
-}
diff --git a/sys/kern/kern_tty.c b/sys/kern/kern_tty.c
deleted file mode 100644
index e47c2e2..0000000
--- a/sys/kern/kern_tty.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/tty.h>
-#include <sys/system.h>
-#include <sys/cdefs.h>
-#include <sys/errno.h>
-#include <sys/syslog.h>
-#include <sys/ascii.h>
-#include <dev/vcons/vcons_io.h>
-#include <fs/devfs.h>
-#include <string.h>
-
-static dev_t tty_major = 0;
-struct tty g_root_tty = {
- .scr = &g_syslog_screen,
- .ring = {
- .enq_index = 0,
- .deq_index = 0,
- },
- .termios = {
- .c_lflag = ICANON | ECHO
- }
-};
-
-static inline dev_t
-tty_alloc_id(void)
-{
- static dev_t id = 1;
-
- return id++;
-}
-
-static inline bool
-tty_is_special(char c)
-{
- return c < 0x1F;
-}
-
-static inline void
-tty_reset_ring(struct tty_ring *ring)
-{
- ring->enq_index = 0;
- ring->deq_index = 0;
-}
-
-static void
-tty_process(struct tty *tty, char c, bool echo)
-{
- const struct termios *termios;
- bool canon, special;
-
- termios = &tty->termios;
- canon = __TEST(termios->c_lflag, ICANON);
- special = tty_is_special(c);
-
- if (canon && special)
- vcons_process_output(tty->scr, c);
- if (echo && !special)
- vcons_putch(tty->scr, c);
-}
-
-/*
- * Flushes the TTY ring buffer.
- *
- * @tty: TTY to flush.
- *
- * Returns number of bytes flushed.
- */
-static ssize_t
-__tty_flush(struct tty *tty)
-{
- struct tty_ring *ring = &tty->ring;
- struct tty_ring *outring = &tty->outring;
- size_t count = 0;
- char tmp;
-
- /* Do we have any data left? */
- if (ring->deq_index >= ring->enq_index)
- return -EAGAIN;
-
- /*
- * Flush the input ring to the output ring
- * to allow user programs to fetch from it
- * with /dev/ttyN.
- */
- while (ring->deq_index < ring->enq_index) {
- tmp = ring->data[ring->deq_index++];
- outring->data[outring->enq_index++] = tmp;
-
- if (outring->enq_index > TTY_RING_SIZE)
- tty_reset_ring(outring);
-
- ++count;
- }
-
- tty_reset_ring(ring);
- return count;
-}
-
-static int
-tty_dev_read(struct device *dev, struct sio_txn *sio)
-{
- struct tty_ring *ring = &g_root_tty.outring;
- size_t len, max_len;
-
- spinlock_acquire(&g_root_tty.rlock);
- max_len = (ring->enq_index - ring->deq_index);
- len = sio->len;
-
- if (len > max_len)
- len = max_len;
-
- /*
- * Transfer data from the TTY ring with SIO then
- * ensure the ring is clean by resetting it.
- *
- * TODO: As of now we are just reading the root
- * TTY, add support for multiple TTYs.
- */
- memcpy(sio->buf, ring->data, len);
- tty_reset_ring(ring);
- spinlock_release(&g_root_tty.rlock);
- return len;
-}
-
-static int
-tty_dev_ioctl(struct device *dev, uint32_t cmd, uintptr_t arg)
-{
- /* TODO: Support multiple TTYs */
- struct termios *tp = &g_root_tty.termios;
-
- switch (cmd) {
- case TCGETS:
- copyout(tp, arg, sizeof(struct termios));
- break;
- case TCSETS:
- copyin(arg, tp, sizeof(struct termios));
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int
-tty_dev_open(struct device *dev)
-{
- /* TODO: Support multiple TTYs */
- struct tty *tty = &g_root_tty;
- struct tty_ring *ring = &tty->outring;
-
- /* Ensure the ring is clean */
- spinlock_acquire(&tty->rlock);
- tty_reset_ring(ring);
- spinlock_release(&tty->rlock);
- return 0;
-}
-
-/*
- * Serialized wrapper over __tty_flush()
- */
-ssize_t
-tty_flush(struct tty *tty)
-{
- ssize_t ret;
-
- spinlock_acquire(&tty->rlock);
- ret = __tty_flush(tty);
- spinlock_release(&tty->rlock);
- return ret;
-}
-
-/*
- * Write a character to a TTY
- *
- * @tty: TTY to write to.
- * @c: Character to write.
- */
-int
-tty_putc(struct tty *tty, int c, int flags)
-{
- struct tty_ring *ring;
- const struct termios *termios;
- bool canon, echo;
-
- ring = &tty->ring;
- termios = &tty->termios;
-
- canon = __TEST(termios->c_lflag, ICANON);
- echo = __TEST(termios->c_lflag, ECHO);
-
- spinlock_acquire(&tty->rlock);
- ring->data[ring->enq_index++] = c;
-
- /*
- * Process the characters for both device input
- * and raw input. Device input will only be echoed
- * if the ECHO bit is set within c_lflag
- */
- if (__TEST(flags, TTY_SOURCE_DEV) && echo)
- tty_process(tty, c, echo);
- if (__TEST(flags, TTY_SOURCE_RAW))
- tty_process(tty, c, true);
-
- /*
- * If we are in canonical mode and we have a linefeed ('\n')
- * character, we should flush the ring.
- */
- if (canon && c == ASCII_LF) {
- __tty_flush(tty);
- }
-
- /*
- * Just flush the ring if we aren't in canonical
- * mode.
- */
- if (!canon) {
- __tty_flush(tty);
- }
-
- /* Reset the ring if it is full */
- if (ring->enq_index >= TTY_RING_SIZE) {
- tty_reset_ring(ring);
- }
-
- spinlock_release(&tty->rlock);
- return 0;
-}
-
-/*
- * Write a string to a TTY
- *
- * @tty: TTY to write to.
- * @s: String to write.
- * @count: Number of bytes to write.
- */
-int
-tty_putstr(struct tty *tty, const char *s, size_t count)
-{
- for (size_t i = 0; i < count; ++i) {
- tty_putc(tty, *s++, TTY_SOURCE_RAW);
- }
-
- return 0;
-}
-
-dev_t
-tty_attach(struct tty *tty)
-{
- int tmp;
- char devname[128];
- struct device *dev = device_alloc();
-
- if (dev == NULL)
- return -ENOMEM;
-
- /*
- * Allocate a major for the driver if we don't
- * have one yet.
- */
- if (tty_major == 0)
- tty_major = device_alloc_major();
-
- /* Now try to create the device */
- tty->id = tty_alloc_id();
- if ((tmp = device_create(dev, tty_major, tty->id)) < 0)
- return tmp;
-
- dev->read = tty_dev_read;
- dev->ioctl = tty_dev_ioctl;
- dev->open = tty_dev_open;
- dev->blocksize = 1;
-
- snprintf(devname, sizeof(devname), "tty%d", tty->id);
- return devfs_add_dev(devname, dev);
-}
diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c
deleted file mode 100644
index 6754b1f..0000000
--- a/sys/kern/vfs_init.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/vfs.h>
-#include <sys/cdefs.h>
-#include <sys/mount.h>
-#include <sys/types.h>
-#include <sys/vnode.h>
-#include <fs/initramfs.h>
-#include <fs/devfs.h>
-#include <fs/procfs.h>
-#include <assert.h>
-#include <string.h>
-
-__MODULE_NAME("vfs");
-__KERNEL_META("$Hyra$: vfs.c, Ian Marco Moffett, "
- "Hyra Virtual File System");
-
-#define INITRAMFS_ID 0
-#define DEVFS_ID 1
-#define PROCFS_ID 2
-
-static struct fs_info filesystems[] = {
- [INITRAMFS_ID] = { "initramfs", &g_initramfs_ops, NULL},
- [DEVFS_ID] = { "dev", &g_devfs_ops, &g_devfs_vops },
- [PROCFS_ID] = { "proc", &g_procfs_ops, &g_procfs_vops }
-};
-
-struct vnode *g_root_vnode = NULL;
-
-struct fs_info *
-vfs_byname(const char *name)
-{
- for (int i = 0; i < __ARRAY_COUNT(filesystems); ++i) {
- if (strcmp(filesystems[i].name, name) == 0) {
- return &filesystems[i];
- }
- }
-
- return NULL;
-}
-
-void
-vfs_init(void)
-{
- struct fs_info *info;
- struct vfsops *vfsops;
-
- vfs_mount_init();
- __assert(vfs_alloc_vnode(&g_root_vnode, NULL, VDIR) == 0);
-
- for (int i = 0; i < __ARRAY_COUNT(filesystems); ++i) {
- info = &filesystems[i];
- vfsops = info->vfsops;
-
- __assert(vfsops->init != NULL);
- __assert(vfs_mount(info->name, 0, info) == 0);
- vfsops->init(info, NULL);
- }
-
- g_root_vnode->vops = &g_initramfs_vops;
- g_root_vnode->fs = &filesystems[INITRAMFS_ID];
-}
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
deleted file mode 100644
index ea73d1a..0000000
--- a/sys/kern/vfs_lookup.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/vfs.h>
-#include <sys/mount.h>
-#include <sys/errno.h>
-#include <vm/dynalloc.h>
-#include <string.h>
-
-/*
- * Fetches the filename within a path at
- * the nth index denoted by `idx'
- *
- * Returns memory allocated by dynalloc()
- * containing the filename.
- *
- * XXX: MUST FREE RETURN VALUE WITH dynfree() WHEN
- * DONE!
- */
-char *
-vfs_get_fname_at(const char *path, size_t idx)
-{
- size_t pathlen = strlen(path);
- size_t fname_len;
-
- char *path_tmp = dynalloc(pathlen + 2);
- char *ret = NULL;
- char *start_ptr, *ptr;
-
- /* Make one-based */
- ++idx;
-
- if (path_tmp == NULL) {
- return NULL;
- }
-
- ptr = path_tmp;
- memcpy(path_tmp, path, pathlen + 1);
-
- /*
- * We want to by default have a '/' at the end
- * to keep the parsing logic from getting more
- * complicated than it needs to be.
- */
- path_tmp[pathlen] = '/';
- path_tmp[pathlen + 1] = '\0';
-
- /* Skip any leading slashes */
- while (*ptr == '/')
- ++ptr;
-
- start_ptr = ptr;
-
- /* Get each filename */
- while (*ptr != '\0') {
- /* Handle duplicate delimiter */
- if (*ptr == '/' && *(ptr + 1) == '/') {
- /*
- * Snip this delimiter and skip, the next
- * will be read and filename returned (if of course
- * the index is reached).
- */
- *(ptr++) = '\0';
- continue;
- }
-
- if (*ptr == '/') {
- *(ptr++) = '\0';
-
- /* Continue if index not reached */
- if ((--idx) != 0) {
- start_ptr = ptr;
- continue;
- }
-
- /* Index has been reached, start_ptr contains name */
- fname_len = strlen(start_ptr);
- ret = dynalloc(fname_len + 1);
-
- if (ret != NULL) {
- memcpy(ret, start_ptr, fname_len + 1);
- }
- break;
- }
-
- ++ptr;
- }
-
- dynfree(path_tmp);
- return ret;
-}
-
-/*
- * Fetches a vnode from a path.
- *
- * @path: Path to fetch vnode from.
- * @vp: Output var for fetched vnode.
- *
- * Returns 0 on success.
- */
-int
-vfs_path_to_node(const char *path, struct vnode **vp)
-{
- struct vnode *vnode = g_root_vnode;
- struct mount *mp;
- struct fs_info *fs;
- char *name;
- int s = 0, fs_caps = 0;
-
- if (strcmp(path, "/") == 0 || !vfs_is_valid_path(path)) {
- return -EINVAL;
- } else if (*path != '/') {
- return -EINVAL;
- }
-
- /* See if we have a mountpoint with this name */
- name = vfs_get_fname_at(path, 0);
- if (vfs_get_mp(name, &mp) == 0) {
- fs = mp->fs;
- vnode = fs->vnode;
- }
-
- /* Fetch filesystem capabilities if we can */
- if (vnode->fs != NULL) {
- fs = vnode->fs;
- fs_caps = fs->caps;
- }
-
- /*
- * If the filesystem requires full-path lookups, we can try
- * throwing the full path at the filesystem to see if
- * it'll give us a vnode.
- */
- if (__TEST(fs_caps, FSCAP_FULLPATH)) {
- s = vfs_vget(vnode, path, &vnode);
- goto done;
- }
-
- for (size_t i = 1;; ++i) {
- name = vfs_get_fname_at(path, i);
- if (name == NULL) break;
-
- s = vfs_vget(vnode, name, &vnode);
- dynfree(name);
-
- if (s != 0) break;
- }
-
-done:
- if (vp != NULL && s == 0) {
- *vp = vnode;
- }
-
- return s;
-}
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
deleted file mode 100644
index 27d0ec3..0000000
--- a/sys/kern/vfs_mount.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/queue.h>
-#include <sys/mount.h>
-#include <sys/vfs.h>
-#include <sys/errno.h>
-#include <vm/dynalloc.h>
-#include <assert.h>
-#include <string.h>
-
-/* TODO: Make this more flexible */
-#define MOUNTLIST_SIZE 8
-
-/* Mountlist entry */
-struct mountlist_entry {
- TAILQ_HEAD(, mount) buckets;
-};
-
-static struct mountlist_entry *mountlist = NULL;
-
-static int
-vfs_create_mp(const char *path, int mntflags, struct mount **mp_out)
-{
- struct mount *mp;
-
- mp = dynalloc(sizeof(struct mount));
- if (mp == NULL) {
- return -ENOMEM;
- }
-
- mp->flags = mntflags;
- *mp_out = mp;
- return 0;
-}
-
-static int
-mount(const char *source, const char *target, const char *filesystemtype,
- unsigned long mountflags, const void *data)
-{
- struct vnode *source_vnode;
- struct fs_info *info;
- int status;
-
- if (source == NULL || target == NULL || filesystemtype == NULL)
- return -EFAULT;
-
- /*
- * Check mount flags.
- *
- * XXX: No flags implemented yet.
- */
- if (mountflags != 0)
- return -EINVAL;
-
- /* Locate source, if any */
- if (strcmp(source, "none") == 0) {
- source_vnode = NULL;
- } else {
- status = vfs_path_to_node(source, &source_vnode);
- if (status != 0)
- return status;
- }
-
- /* Locate filesystem */
- info = vfs_byname(filesystemtype);
- if (info == NULL)
- return -ENODEV;
-
- /* Create mount point */
- status = vfs_mount(target, 0, info);
- if (status != 0)
- return status;
-
- /* Initialize filesystem if needed */
- if (info->vfsops->init != NULL)
- return info->vfsops->init(info, source_vnode);
-
- return 0;
-}
-
-/*
- * Mount a mountpoint
- *
- * @path: Path this mountpoint belongs to
- * @mntflags: Flags to mount with
- * @fs: Filesystem to mount
- *
- * If this mount entry already exists, -EEXIST
- * will be returned.
- */
-int
-vfs_mount(const char *path, int mntflags, struct fs_info *fs)
-{
- size_t hash;
- int status;
- struct mountlist_entry *entry;
- struct mount *mp;
-
- /* Exclude leading slash */
- if (*path == '/') {
- ++path;
- }
-
- hash = vfs_hash_path(path);
-
- if ((status = vfs_create_mp(path, mntflags, &mp)) != 0) {
- return status;
- }
-
- if (hash == -1) {
- /* Something is wrong with the path */
- return -EINVAL;
- }
-
- if (vfs_get_mp(path, NULL) == 0) {
- /* mount hit, do not duplicate this entry */
- return -EEXIST;
- }
-
- if ((status = vfs_alloc_vnode(&fs->vnode, mp, VDIR)) != 0) {
- return status;
- }
-
- mp->phash = hash;
- mp->fs = fs;
- fs->vnode->vops = fs->vops;
-
- entry = &mountlist[hash % MOUNTLIST_SIZE];
- TAILQ_INSERT_TAIL(&entry->buckets, mp, link);
- return 0;
-}
-
-/*
- * Fetch mountpoint
- *
- * @path: Path of target mountpoint
- * @mp: Pointer of variable where mountpoint fetched will
- * be stored
- *
- * Returns 0 upon a mplist hit, on a mplist miss this
- * function returns -ENOENT.
- */
-int
-vfs_get_mp(const char *path, struct mount **mp)
-{
- size_t hash;
- struct mountlist_entry *entry;
- struct mount *mount_iter;
-
- /* Exclude leading slash */
- if (*path == '/') {
- ++path;
- }
-
- hash = vfs_hash_path(path);
-
- if (hash == 0) {
- /* Something is wrong with the path */
- return -EINVAL;
- }
-
- entry = &mountlist[hash % MOUNTLIST_SIZE];
- TAILQ_FOREACH(mount_iter, &entry->buckets, link) {
- if (mount_iter->phash == hash) {
- if (mp != NULL) *mp = mount_iter;
- return 0;
- }
- }
-
- return -ENOENT;
-}
-
-void
-vfs_mount_init(void)
-{
- mountlist = dynalloc(sizeof(struct mountlist_entry) * MOUNTLIST_SIZE);
- __assert(mountlist != NULL);
-
- for (size_t i = 0; i < MOUNTLIST_SIZE; ++i) {
- TAILQ_INIT(&mountlist[i].buckets);
- }
-}
-
-uint64_t
-sys_mount(struct syscall_args *args)
-{
- return mount((void *)args->arg0, (void *)args->arg1, (void *)args->arg2,
- (unsigned long)args->arg3, (void *)args->arg4);
-}
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
deleted file mode 100644
index 60afa31..0000000
--- a/sys/kern/vfs_subr.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (c) 2023-2024 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/vfs.h>
-#include <sys/errno.h>
-#include <sys/mount.h>
-#include <vm/dynalloc.h>
-#include <string.h>
-
-/* FNV-1a defines */
-#define FNV_OFFSET 14695981039346656037ULL
-#define FNV_PRIME 1099511628211ULL
-
-/*
- * FNV-1a hash function
- * https://en.wikipedia.org/wiki/Fowler–Noll–Vo_hash_function
- */
-static size_t
-vfs_hash(const char *data)
-{
- size_t hash = FNV_OFFSET;
- const char *p = data;
-
- while (*p) {
- hash ^= (size_t)(uint8_t)(*p);
- hash *= FNV_PRIME;
- ++p;
- }
-
- return hash;
-}
-
-/*
- * Hashes a path
- *
- * @path: Path to hash.
- *
- * Returns -1 on failure, >= 0 return values
- * are valid.
- */
-ssize_t
-vfs_hash_path(const char *path)
-{
- char *name = NULL;
- size_t i = 0, hash = 0;
-
- if (strcmp(path, "/") == 0 || !vfs_is_valid_path(path)) {
- return -1;
- }
-
- do {
- name = vfs_get_fname_at(path, i++);
- if (name != NULL) {
- hash += vfs_hash(name);
- dynfree(name);
- }
- } while (name != NULL);
-
- return hash;
-}
-
-
-/*
- * This function checks if a path is valid.
- *
- * @path: Path to check.
- *
- * Returns true if valid, otherwise false.
- */
-bool
-vfs_is_valid_path(const char *path)
-{
- const char *ptr = path;
- char c;
-
- while (*ptr != '\0') {
- c = *(ptr++);
- switch (c) {
- case '/':
- case '-':
- case '_':
- case '.':
- /* Valid char, can continue */
- continue;
- default:
- /*
- * This could be an alphabetical or "numeric" char which
- * is valid. We want to handle this too. To make things
- * easier we'll OR the char by 0x20 to convert it to
- * lowercase if it is alphabetical.
- */
- c |= 0x20;
- if (c >= 'a' && c <= 'z')
- continue;
- else if (c >= '0' && c <= '9')
- continue;
-
- /* We got an invalid char */
- return false;
- }
- }
-
- return true;
-}
-
-/*
- * Allocates a vnode
- *
- * @vnode: Pointer to vnode pointer where newly allocated
- * vnode will be stored.
- *
- * @mp: Mountpoint this vnode is associated with.
- * @type: Vnode type.
- *
- * This function will return 0 upon success and < 0 on failure.
- */
-int
-vfs_alloc_vnode(struct vnode **vnode, struct mount *mp, int type)
-{
- struct vnode *new_vnode = dynalloc(sizeof(struct vnode));
-
- if (new_vnode == NULL) {
- return -ENOMEM;
- }
-
- memset(new_vnode, 0, sizeof(struct vnode));
- new_vnode->type = type;
- new_vnode->mp = mp;
-
- *vnode = new_vnode;
- return 0;
-}
-
-/*
- * Returns the rootname of a path
- * For example, "/foo/bar/" will be "foo" and
- * "/foo/bar/baz" will also be "foo"
- *
- * There will be no slashes in the returned string
- * unless "/" is passed.
- *
- * XXX: Returns memory allocated by dynalloc,
- * remember to free the memory with dynfree()
- *
- * @path: Path to get rootname of
- * @new_path: New path will be placed here.
- */
-int
-vfs_rootname(const char *path, char **new_path)
-{
- char *tmp = NULL;
- const char *ptr = path;
- size_t len = 0;
-
- if (!vfs_is_valid_path(path)) {
- *new_path = NULL;
- return -EINVAL;
- }
-
- if (*path == '/') {
- /* Skip first '/' */
- ++ptr;
- ++path;
- }
-
- for (; *ptr != '\0' && *ptr != '/'; ++ptr) {
- if (*ptr == '/') {
- break;
- }
- ++len;
- }
-
- tmp = dynalloc(sizeof(char) * len + 1);
- if (tmp == NULL) {
- *new_path = NULL;
- return -ENOMEM;
- }
-
- if (len == 0) {
- /* Handle input that is just "/" */
- tmp[0] = '/';
- tmp[1] = '\0';
- } else {
- memcpy(tmp, path, len + 2);
- }
-
- *new_path = tmp;
- return 0;
-}
-
-
-int
-vfs_vget(struct vnode *parent, const char *name, struct vnode **vp)
-{
- return parent->vops->vget(parent, name, vp);
-}
-
-ssize_t
-vfs_read(struct vnode *vp, struct sio_txn *sio)
-{
- return vp->vops->read(vp, sio);
-}
-
-ssize_t
-vfs_write(struct vnode *vp, struct sio_txn *sio)
-{
- return vp->vops->write(vp, sio);
-}
-
-int
-vfs_getattr(struct vnode *vp, struct vattr *vattr)
-{
- return vp->vops->getattr(vp, vattr);
-}
-
-int vfs_open(struct vnode *vp)
-{
- if (vp->vops->open == NULL)
- return -EIO;
-
- return vp->vops->open(vp);
-}
-
-int
-vfs_close(struct vnode *vp)
-{
- if (vp->vops->close == NULL)
- return -EIO;
-
- return vp->vops->close(vp);
-}