summaryrefslogtreecommitdiff
path: root/src/sys
diff options
context:
space:
mode:
Diffstat (limited to 'src/sys')
-rw-r--r--src/sys/arch/amd64/conf/GENERIC4
-rw-r--r--src/sys/arch/amd64/cpu/cpu_mp.c14
-rw-r--r--src/sys/arch/amd64/cpu/trap.c5
-rw-r--r--src/sys/arch/amd64/isa/i8042.c35
-rw-r--r--src/sys/arch/amd64/os/os_proc.c19
-rw-r--r--src/sys/compat/unix/os/os_filedesc.c11
-rw-r--r--src/sys/compat/unix/os/proc_syscall.c2
-rw-r--r--src/sys/include/compat/unix/syscall.h8
-rw-r--r--src/sys/include/os/filedesc.h12
-rw-r--r--src/sys/include/os/vnode.h20
-rw-r--r--src/sys/include/sys/proc.h17
-rw-r--r--src/sys/include/sys/syscall.h1
-rw-r--r--src/sys/os/os_filedes.c47
-rw-r--r--src/sys/os/os_init.c5
-rw-r--r--src/sys/os/os_omar.c6
-rw-r--r--src/sys/os/os_proc.c30
-rw-r--r--src/sys/os/vfs_subr.c27
17 files changed, 236 insertions, 27 deletions
diff --git a/src/sys/arch/amd64/conf/GENERIC b/src/sys/arch/amd64/conf/GENERIC
index 93919d8..f402941 100644
--- a/src/sys/arch/amd64/conf/GENERIC
+++ b/src/sys/arch/amd64/conf/GENERIC
@@ -2,3 +2,7 @@
// as a method. Some firmware (e.g., on some laptops)
// may not handle these well and hang.
option I8042_REBOOT yes
+
+// Controls if the i8042 should be polled
+// rather than dependent on interrupts
+option I8042_POLL no
diff --git a/src/sys/arch/amd64/cpu/cpu_mp.c b/src/sys/arch/amd64/cpu/cpu_mp.c
index ae7b367..7b691e3 100644
--- a/src/sys/arch/amd64/cpu/cpu_mp.c
+++ b/src/sys/arch/amd64/cpu/cpu_mp.c
@@ -56,10 +56,19 @@ static volatile struct limine_smp_request g_smp_req = {
.revision = 0
};
+static void
+cpu_idle(void *)
+{
+ for (;;) {
+ __ASMV("pause");
+ }
+}
+
__dead static void
ap_entry(struct limine_smp_info *)
{
struct pcore *pcore;
+ struct proc *curidle;
spinlock_acquire(&lock);
pcore = kalloc(sizeof(*pcore));
@@ -76,9 +85,10 @@ ap_entry(struct limine_smp_info *)
corelist[ncores_up - 1] = pcore;
atomic_inc_64(&ncores_up);
+ proc_ktd(&curidle, cpu_idle);
spinlock_release(&lock);
- md_proc_yield();
+ md_proc_idle();
__builtin_unreachable();
for (;;);
}
@@ -106,6 +116,7 @@ bsp_ap_startup(void)
struct limine_smp_response *resp = g_smp_req.response;
struct limine_smp_info **cpus;
struct mdcore *mdcore;
+ struct proc *curidle;
uint32_t ncores, tmp;
/* Sanity check */
@@ -139,6 +150,7 @@ bsp_ap_startup(void)
printf("mp: bringing APs online...\n");
mdcore = &g_bsp.md;
+ proc_ktd(&curidle, cpu_idle);
for (int i = 0; i < ncores; ++i) {
if (mdcore->apic_id == cpus[i]->lapic_id) {
continue;
diff --git a/src/sys/arch/amd64/cpu/trap.c b/src/sys/arch/amd64/cpu/trap.c
index 921a036..ae3a0cc 100644
--- a/src/sys/arch/amd64/cpu/trap.c
+++ b/src/sys/arch/amd64/cpu/trap.c
@@ -39,6 +39,7 @@
#include <sys/syslog.h>
#include <sys/syscall.h>
#include <machine/trap.h>
+#include <string.h>
/*
* Trap type to type string conversion table
@@ -154,6 +155,7 @@ trap_syscall(struct trapframe *tf)
struct syscall_domain *scdp;
struct syscall_win *scwp;
struct proc *self;
+ struct md_pcb *pcbp;
struct syscall_args scargs = {
.arg[0] = tf->rdi,
.arg[1] = tf->rsi,
@@ -179,6 +181,9 @@ trap_syscall(struct trapframe *tf)
return;
}
+ pcbp = &self->pcb;
+ memcpy(&pcbp->tf, tf, sizeof(pcbp->tf));
+
if (tf->rax < scwp->nimpl && tf->rax > 0) {
tf->rax = scwp->sctab[tf->rax](&scargs);
}
diff --git a/src/sys/arch/amd64/isa/i8042.c b/src/sys/arch/amd64/isa/i8042.c
index 9417206..6ffea73 100644
--- a/src/sys/arch/amd64/isa/i8042.c
+++ b/src/sys/arch/amd64/isa/i8042.c
@@ -40,6 +40,12 @@
#include <machine/pio.h>
#include <stdbool.h>
+#if defined(__I8042_POLL)
+#define I8042_POLL __I8042_POLL
+#else
+#define I8042_POLL 0
+#endif /* !I8042_POLL */
+
#define RING_NENT 16
/*
@@ -58,6 +64,7 @@ struct keybuf {
/* I/O tap forward declarations */
static struct iotap_ops tap_port0_ops;
static struct iotap_desc tap_port0;
+static struct proc *kbd_poll_td;
/* Key states */
static bool shift_key = false;
@@ -350,6 +357,20 @@ i8042_irq(struct intr_hand *hp)
return 1;
}
+static void
+i8042_poll(void *p)
+{
+ char c;
+ uint8_t scancode;
+
+ for (;;) {
+ scancode = i8042_read();
+ if (i8042_getc(scancode, &c) == 0) {
+ keybuf_enter(&buf, c);
+ }
+ }
+}
+
/*
* Initialize i8042 interrupts (IRQ 1)
*/
@@ -399,8 +420,18 @@ i8042_init(struct module *modp)
i8042_write(true, I8042_DISABLE_PORT1);
i8042_read();
- /* Initialize interrupts and taps */
- i8042_init_intr();
+ /*
+ * If we are configured to do interrupts, enable
+ * them. Otherwise, start a kernel thread and
+ * poll.
+ */
+ if (!I8042_POLL) {
+ i8042_init_intr();
+ } else {
+ proc_ktd(&kbd_poll_td, i8042_poll);
+ }
+
+ /* Enable I/O taps */
i8042_init_tap();
/* Enable the keyboard */
diff --git a/src/sys/arch/amd64/os/os_proc.c b/src/sys/arch/amd64/os/os_proc.c
index 93e5d73..23948ab 100644
--- a/src/sys/arch/amd64/os/os_proc.c
+++ b/src/sys/arch/amd64/os/os_proc.c
@@ -112,8 +112,14 @@ md_proc_init(struct proc *procp, int flags)
return error;
}
- ds = USER_DS | 3;
- cs = USER_CS | 3;
+ if (ISSET(flags, SPAWN_KTD)) {
+ ds = KERNEL_DS;
+ cs = KERNEL_CS;
+ procp->flags |= PROC_KTD;
+ } else {
+ ds = USER_DS | 3;
+ cs = USER_CS | 3;
+ }
/*
* Set up the mapping specifier, we'll use zero
@@ -146,7 +152,7 @@ md_proc_init(struct proc *procp, int flags)
* Process idle loop
*/
__dead void
-md_proc_yield(void)
+md_proc_idle(void)
{
struct proc *proc;
struct pcore *core = this_core();
@@ -161,11 +167,6 @@ md_proc_yield(void)
*/
for (;;) {
lapic_timer_oneshot_us(9000);
- error = sched_deq(&core->scq, &proc);
- if (error == 0) {
- core->curproc = proc;
- md_proc_kick(proc);
- }
__ASMV("sti; hlt");
}
}
@@ -288,7 +289,7 @@ md_proc_kill(struct proc *procp, int flags)
/* If this is us, spin time */
if (self->pid == procp->pid) {
core->curproc = NULL;
- md_proc_yield();
+ md_proc_idle();
}
return 0;
diff --git a/src/sys/compat/unix/os/os_filedesc.c b/src/sys/compat/unix/os/os_filedesc.c
index 673701f..952f022 100644
--- a/src/sys/compat/unix/os/os_filedesc.c
+++ b/src/sys/compat/unix/os/os_filedesc.c
@@ -138,3 +138,14 @@ sys_read(struct syscall_args *scargs)
kfree(kbuf);
return (error == 0) ? retval : error;
}
+
+/*
+ * ARG0: FD
+ */
+scret_t
+sys_close(struct syscall_args *scargs)
+{
+ int fd = SCARG(scargs, int, 0);
+
+ return fd_close(fd);
+}
diff --git a/src/sys/compat/unix/os/proc_syscall.c b/src/sys/compat/unix/os/proc_syscall.c
index 1838761..634ebf3 100644
--- a/src/sys/compat/unix/os/proc_syscall.c
+++ b/src/sys/compat/unix/os/proc_syscall.c
@@ -46,5 +46,5 @@ sys_exit(struct syscall_args *scargs)
status = SCARG(scargs, int, 0);
proc_kill(core->curproc, status);
- md_proc_yield(); /* unreachable */
+ md_proc_idle(); /* unreachable */
}
diff --git a/src/sys/include/compat/unix/syscall.h b/src/sys/include/compat/unix/syscall.h
index be351e8..a031872 100644
--- a/src/sys/include/compat/unix/syscall.h
+++ b/src/sys/include/compat/unix/syscall.h
@@ -68,6 +68,11 @@ scret_t sys_open(struct syscall_args *scargs);
*/
scret_t sys_read(struct syscall_args *scargs);
+/*
+ * Close a file
+ */
+scret_t sys_close(struct syscall_args *scargs);
+
#ifdef _NEED_UNIX_SCTAB
scret_t(*g_unix_sctab[])(struct syscall_args *) = {
[SYS_none] = NULL,
@@ -83,7 +88,8 @@ scret_t(*g_unix_sctab[])(struct syscall_args *) = {
[SYS_reboot] = sys_reboot,
[SYS_waitpid] = sys_waitpid,
[SYS_dmsio] = sys_dmsio,
- [SYS_read] = sys_read
+ [SYS_read] = sys_read,
+ [SYS_close] = sys_close
};
#endif /* !_NEED_UNIX_SCTAB */
diff --git a/src/sys/include/os/filedesc.h b/src/sys/include/os/filedesc.h
index 8cdf161..a6a2ac5 100644
--- a/src/sys/include/os/filedesc.h
+++ b/src/sys/include/os/filedesc.h
@@ -39,11 +39,13 @@ struct proc;
* Represents a file descriptor
*
* @fdno: File descriptor index
+ * @off: Current file offset
* @vp: Vnode this fd is linked with
* @mode: File attributes
*/
struct filedesc {
int fdno;
+ off_t off;
struct vnode *vp;
mode_t mode;
};
@@ -82,6 +84,16 @@ int fdtab_init(struct proc *procp);
int fd_open(const char *path, mode_t mode);
/*
+ * Close a file
+ *
+ * @fd: File descriptor to close
+ *
+ * Returns zero on success, otherwise a less than
+ * zero value on failure
+ */
+int fd_close(int fd);
+
+/*
* Write to a file descriptor
*
* @fd: File descriptor to write to
diff --git a/src/sys/include/os/vnode.h b/src/sys/include/os/vnode.h
index 868e137..1bef1e2 100644
--- a/src/sys/include/os/vnode.h
+++ b/src/sys/include/os/vnode.h
@@ -72,11 +72,13 @@ struct vop_lookup_args {
*
* @data: Buffer containing I/O data
* @len: Length of buffer
+ * @off: Offset of operation
* @vp: Current vnode
*/
struct vop_rw_data {
void *data;
size_t len;
+ off_t off;
struct vnode *vp;
};
@@ -86,6 +88,7 @@ struct vop_rw_data {
*/
struct vop {
int(*lookup)(struct vop_lookup_args *args);
+ int(*reclaim)(struct vnode *vp, int flags);
ssize_t(*write)(struct vop_rw_data *data);
ssize_t(*read)(struct vop_rw_data *data);
};
@@ -141,23 +144,36 @@ int vfs_vrel(struct vnode *vp, int flags);
*
* @vp: Vnode to write to
* @data: Data to write
+ * @off: Offset to write at
* @len: Length of bytes to write
*
* Returns the number of bytes written on success, otherwise
* a less than zero value on failure.
*/
-ssize_t vop_write(struct vnode *vp, char *data, size_t len);
+ssize_t vop_write(struct vnode *vp, char *data, off_t off, size_t len);
/*
* Wrapper for the read write callback
*
* @vp: Vnode to read from
* @data: Read data written here
+ * @off: Offset to read at
* @len: Length of bytes to read
*
* Returns the number of bytes read on success, otherwise
* a less than zero value on failure.
*/
-ssize_t vop_read(struct vnode *vp, char *data, size_t len);
+ssize_t vop_read(struct vnode *vp, char *data, off_t off, size_t len);
+
+/*
+ * Reclaim the resources tied to a specific vnode
+ *
+ * @vp: Vnode to reclaim
+ * @flags: Optional flags
+ *
+ * Returns zero on success, otherwise a less than zero value
+ * on failure.
+ */
+int vop_reclaim(struct vnode *vp, int flags);
#endif /* !_OS_VNODE_H_ */
diff --git a/src/sys/include/sys/proc.h b/src/sys/include/sys/proc.h
index 618ddf3..a547233 100644
--- a/src/sys/include/sys/proc.h
+++ b/src/sys/include/sys/proc.h
@@ -101,6 +101,10 @@ struct proc {
#define PROC_EXITING BIT(0) /* Process is exiting */
#define PROC_SLEEPING BIT(1) /* Process is sleeping */
+#define PROC_KTD BIT(2) /* Process is kernel thread */
+
+/* Flags for PROC_SPAWN */
+#define SPAWN_KTD BIT(0) /* Spawn kernel thread */
/*
* Initialize a process into a basic minimal
@@ -136,6 +140,14 @@ struct proc *proc_self(void);
int proc_add_range(struct proc *procp, vaddr_t va, paddr_t pa, size_t len);
/*
+ * Spawn a kernel thread
+ *
+ * @procp_res: Result is written here
+ * @fn: Function where kernel thread should end up
+ */
+int proc_ktd(struct proc **procp_res, void(*fn)(void *));
+
+/*
* Kill a process with a specific status code
*
* @procp: Process to kill
@@ -210,8 +222,7 @@ int proc_check_addr(struct proc *proc, uintptr_t addr, size_t len);
*
* @proc: Process to put to sleep
*
- * Returns zero if the address is within the process bounds,
- * otherwise a less than zero value on failure.
+ * Returns zero on success
*/
int proc_sleep(struct proc *proc);
@@ -244,7 +255,7 @@ void md_proc_sleep(void);
* Put the current process into a halt loop
* until the next one runs.
*/
-__dead void md_proc_yield(void);
+__dead void md_proc_idle(void);
/*
* Kick a process into a user context
diff --git a/src/sys/include/sys/syscall.h b/src/sys/include/sys/syscall.h
index 1138029..77b7505 100644
--- a/src/sys/include/sys/syscall.h
+++ b/src/sys/include/sys/syscall.h
@@ -57,6 +57,7 @@
#define SYS_waitpid 0x0C /* wait for child to exit */
#define SYS_dmsio 0x0D /* DMS I/O */
#define SYS_read 0x0E /* read a file descriptor */
+#define SYS_close 0x0F /* close a file */
typedef __ssize_t scret_t;
typedef __ssize_t scarg_t;
diff --git a/src/sys/os/os_filedes.c b/src/sys/os/os_filedes.c
index 9ba0c63..95452af 100644
--- a/src/sys/os/os_filedes.c
+++ b/src/sys/os/os_filedes.c
@@ -197,6 +197,32 @@ fd_open(const char *path, mode_t mode)
return fd->fdno;
}
+int
+fd_close(int fd)
+{
+ struct filedesc *fdp;
+ struct proc *proc = proc_self();
+ struct vnode *vp;
+
+ if (fd < 0) {
+ return -EBADF;
+ }
+
+ if (proc == NULL) {
+ return -EIO;
+ }
+
+ if ((fdp = fd_get(proc, fd)) == NULL) {
+ return -EIO;
+ }
+
+ vp = fdp->vp;
+ proc->fdtab[fdp->fdno] = NULL;
+
+ kfree(fdp);
+ return vop_reclaim(vp, 0);
+}
+
/*
* Initialize file descriptor table
*/
@@ -227,8 +253,9 @@ write(int fd, const void *buf, size_t count)
{
struct proc *self = proc_self();
struct filedesc *fdp;
- int error;
+ ssize_t retval;
char kbuf[1024];
+ int error;
if (self == NULL) {
return -ESRCH;
@@ -267,7 +294,13 @@ write(int fd, const void *buf, size_t count)
if (fdp->vp == NULL) {
return -EIO;
}
- return vop_write(fdp->vp, kbuf, count);
+ retval = vop_write(fdp->vp, kbuf, fdp->off, count);
+ if (retval <= 0) {
+ return retval;
+ }
+
+ /* Move away from where we wrote */
+ fdp->off += count;
}
return count;
@@ -278,6 +311,7 @@ read(int fd, void *buf, size_t count)
{
struct proc *self = proc_self();
struct filedesc *fdp;
+ ssize_t retval;
int error;
if (buf == NULL) {
@@ -304,7 +338,14 @@ read(int fd, void *buf, size_t count)
return -EIO;
}
- return vop_read(fdp->vp, buf, count);
+ /* Read the file */
+ retval = vop_read(fdp->vp, buf, fdp->off, count);
+ if (retval <= 0) {
+ return retval;
+ }
+
+ fdp->off += count;
+ return retval;
}
/*
diff --git a/src/sys/os/os_init.c b/src/sys/os/os_init.c
index 43468b3..8287f1a 100644
--- a/src/sys/os/os_init.c
+++ b/src/sys/os/os_init.c
@@ -73,14 +73,15 @@ main(void)
vm_init();
cpu_init(&g_bsp);
- bsp_ap_startup();
vfs_init();
ns_init();
+ sched_init();
+ bsp_ap_startup();
+
/* Initialize generic modules */
__MODULES_INIT(MODTYPE_GENERIC);
- sched_init();
core = this_core();
proc_init(&g_rootproc, 0);
core->curproc = &g_rootproc;
diff --git a/src/sys/os/os_omar.c b/src/sys/os/os_omar.c
index 9ad3739..8e63ae7 100644
--- a/src/sys/os/os_omar.c
+++ b/src/sys/os/os_omar.c
@@ -258,7 +258,11 @@ initrd_read(struct vop_rw_data *data)
len = MIN(data->len, np->size);
for (int i = 0; i < len; ++i) {
- dest[i] = src[i];
+ if ((i + data->off) >= np->size) {
+ /* End of file */
+ return 0;
+ }
+ dest[i] = src[data->off + i];
}
return len;
diff --git a/src/sys/os/os_proc.c b/src/sys/os/os_proc.c
index 582c077..a8f49d7 100644
--- a/src/sys/os/os_proc.c
+++ b/src/sys/os/os_proc.c
@@ -393,6 +393,36 @@ proc_spawn(const char *path, struct penv_blk *envbp)
return proc->pid;
}
+int
+proc_ktd(struct proc **procp_res, void(*fn)(void *))
+{
+ struct proc *proc;
+ struct pcore *core;
+
+ if (procp_res == NULL || fn == NULL) {
+ return -EINVAL;
+ }
+
+ proc = kalloc(sizeof(*proc));
+ if (proc == NULL) {
+ return -ENOMEM;
+ }
+
+ core = cpu_sched();
+ if (core == NULL) {
+ kfree(proc);
+ return -EIO;
+ }
+
+ proc_init(proc, SPAWN_KTD);
+ md_set_ip(proc, (uintptr_t)fn);
+ sched_enq(&core->scq, proc);
+
+ *procp_res = proc;
+ TAILQ_INSERT_TAIL(&procq, proc, lup_link);
+ return 0;
+}
+
/*
* ARG0: Pathname to spawn
* ARG1: Process environment block
diff --git a/src/sys/os/vfs_subr.c b/src/sys/os/vfs_subr.c
index 47ed468..6cb7767 100644
--- a/src/sys/os/vfs_subr.c
+++ b/src/sys/os/vfs_subr.c
@@ -145,7 +145,7 @@ vfs_cmp_cnt(const char *path)
}
ssize_t
-vop_write(struct vnode *vp, char *data, size_t len)
+vop_write(struct vnode *vp, char *data, off_t off, size_t len)
{
struct vop_rw_data rwdata;
struct vop *vops;
@@ -170,11 +170,12 @@ vop_write(struct vnode *vp, char *data, size_t len)
rwdata.data = data;
rwdata.len = len;
rwdata.vp = vp;
+ rwdata.off = off;
return vops->write(&rwdata);
}
ssize_t
-vop_read(struct vnode *vp, char *data, size_t len)
+vop_read(struct vnode *vp, char *data, off_t off, size_t len)
{
struct vop_rw_data rwdata;
struct vop *vops;
@@ -199,5 +200,27 @@ vop_read(struct vnode *vp, char *data, size_t len)
rwdata.data = data;
rwdata.len = len;
rwdata.vp = vp;
+ rwdata.off = off;
return vops->read(&rwdata);
}
+
+int
+vop_reclaim(struct vnode *vp, int flags)
+{
+ struct vop *vops;
+
+ if (vp == NULL) {
+ return -EINVAL;
+ }
+
+ /* Grab the virtual operations */
+ if ((vops = vp->vops) == NULL) {
+ return -EIO;
+ }
+
+ if (vops->reclaim == NULL) {
+ return -ENOTSUP;
+ }
+
+ return vops->reclaim(vp, flags);
+}