diff options
Diffstat (limited to 'src/sys')
-rw-r--r-- | src/sys/arch/amd64/conf/GENERIC | 4 | ||||
-rw-r--r-- | src/sys/arch/amd64/cpu/cpu_mp.c | 14 | ||||
-rw-r--r-- | src/sys/arch/amd64/cpu/trap.c | 5 | ||||
-rw-r--r-- | src/sys/arch/amd64/isa/i8042.c | 35 | ||||
-rw-r--r-- | src/sys/arch/amd64/os/os_proc.c | 19 | ||||
-rw-r--r-- | src/sys/compat/unix/os/os_filedesc.c | 11 | ||||
-rw-r--r-- | src/sys/compat/unix/os/proc_syscall.c | 2 | ||||
-rw-r--r-- | src/sys/include/compat/unix/syscall.h | 8 | ||||
-rw-r--r-- | src/sys/include/os/filedesc.h | 12 | ||||
-rw-r--r-- | src/sys/include/os/vnode.h | 20 | ||||
-rw-r--r-- | src/sys/include/sys/proc.h | 17 | ||||
-rw-r--r-- | src/sys/include/sys/syscall.h | 1 | ||||
-rw-r--r-- | src/sys/os/os_filedes.c | 47 | ||||
-rw-r--r-- | src/sys/os/os_init.c | 5 | ||||
-rw-r--r-- | src/sys/os/os_omar.c | 6 | ||||
-rw-r--r-- | src/sys/os/os_proc.c | 30 | ||||
-rw-r--r-- | src/sys/os/vfs_subr.c | 27 |
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); +} |