diff options
Diffstat (limited to 'src/kernel')
38 files changed, 478 insertions, 465 deletions
diff --git a/src/kernel/arch/amd64/boot.c b/src/kernel/arch/amd64/boot.c index ed19b79..d78d4f6 100644 --- a/src/kernel/arch/amd64/boot.c +++ b/src/kernel/arch/amd64/boot.c @@ -28,7 +28,7 @@ static void *mbi_tag(void *mbi, uint32_t type) { } void kmain_early(void *mbi) { - struct fb_info vid; + GfxInfo vid; struct { void *addr; size_t len; } init; @@ -78,8 +78,8 @@ void kmain_early(void *mbi) { pci_init(); kprintf("running init...\n"); - process_seed(init.addr, init.len); - process_switch_any(); + proc_seed(init.addr, init.len); + proc_switch_any(); } void shutdown(void) { diff --git a/src/kernel/arch/amd64/driver/fsroot.c b/src/kernel/arch/amd64/driver/fsroot.c index 6217e29..6d3676d 100644 --- a/src/kernel/arch/amd64/driver/fsroot.c +++ b/src/kernel/arch/amd64/driver/fsroot.c @@ -8,7 +8,7 @@ #include <kernel/vfs/request.h> #include <shared/mem.h> -static int handle(struct vfs_request *req) { +static int handle(VfsReq *req) { // TODO document directory read format // TODO don't hardcode const char dir[] = @@ -31,7 +31,7 @@ static int handle(struct vfs_request *req) { } } -static void accept(struct vfs_request *req) { +static void accept(VfsReq *req) { vfsreq_finish_short(req, handle(req)); } diff --git a/src/kernel/arch/amd64/driver/pata.c b/src/kernel/arch/amd64/driver/pata.c index 6928b4e..b0ed592 100644 --- a/src/kernel/arch/amd64/driver/pata.c +++ b/src/kernel/arch/amd64/driver/pata.c @@ -11,13 +11,13 @@ static const int root_id = 100; -static void accept(struct vfs_request *req); +static void accept(VfsReq *req); void pata_init(void) { ata_init(); vfs_root_register("/ata", accept); } -static void accept(struct vfs_request *req) { +static void accept(VfsReq *req) { int ret; long id = (long __force)req->id; char wbuf[4096]; diff --git a/src/kernel/arch/amd64/driver/ps2.c b/src/kernel/arch/amd64/driver/ps2.c index d0629e6..cdcbf19 100644 --- a/src/kernel/arch/amd64/driver/ps2.c +++ b/src/kernel/arch/amd64/driver/ps2.c @@ -17,10 +17,10 @@ static volatile ring_t kb_backlog = {(void*)kb_buf, sizeof kb_buf, 0, 0}; static volatile uint8_t mouse_buf[64]; static volatile ring_t mouse_backlog = {(void*)mouse_buf, sizeof mouse_buf, 0, 0}; -static void accept(struct vfs_request *req); +static void accept(VfsReq *req); -static struct vfs_request *kb_queue = NULL; -static struct vfs_request *mouse_queue = NULL; +static VfsReq *kb_queue = NULL; +static VfsReq *mouse_queue = NULL; static void wait_out(void) { while ((port_in8(PS2 + 4) & 2) != 0); @@ -77,7 +77,7 @@ enum { H_MOUSE, }; -static void accept(struct vfs_request *req) { +static void accept(VfsReq *req) { // when you fix something here go also fix it in the COM1 driver int ret; switch (req->type) { diff --git a/src/kernel/arch/amd64/driver/rtl8139.c b/src/kernel/arch/amd64/driver/rtl8139.c index 1face38..dd11102 100644 --- a/src/kernel/arch/amd64/driver/rtl8139.c +++ b/src/kernel/arch/amd64/driver/rtl8139.c @@ -10,8 +10,8 @@ #define WAIT -1000 -static void accept(struct vfs_request *req); -static struct vfs_request *blocked_on = NULL; +static void accept(VfsReq *req); +static VfsReq *blocked_on = NULL; enum { @@ -105,7 +105,7 @@ void rtl8139_irq(void) { port_out16(iobase + INTRSTATUS, status); } -static int try_rx(struct process *proc, void __user *dest, size_t dlen) { +static int try_rx(Proc *proc, void __user *dest, size_t dlen) { uint16_t flags, size; /* bit 0 - Rx Buffer Empty */ if (port_in8(iobase + CMD) & 1) return WAIT; @@ -140,7 +140,7 @@ static int try_rx(struct process *proc, void __user *dest, size_t dlen) { return size; } -static int try_tx(struct process *proc, const void __user *src, size_t slen) { +static int try_tx(Proc *proc, const void __user *src, size_t slen) { static uint8_t desc = 0; if (slen > 0xFFF) return -1; @@ -164,7 +164,7 @@ static int try_tx(struct process *proc, const void __user *src, size_t slen) { return slen; } -static void accept(struct vfs_request *req) { +static void accept(VfsReq *req) { if (!req->caller) { vfsreq_finish_short(req, -1); return; diff --git a/src/kernel/arch/amd64/driver/serial.c b/src/kernel/arch/amd64/driver/serial.c index 12c4151..6fe4500 100644 --- a/src/kernel/arch/amd64/driver/serial.c +++ b/src/kernel/arch/amd64/driver/serial.c @@ -14,8 +14,8 @@ static volatile ring_t backlog = {(void*)backlog_buf, sizeof backlog_buf, 0, 0}; static const int COM1 = 0x3f8; -static void accept(struct vfs_request *req); -static struct vfs_request *hung_reads = NULL; +static void accept(VfsReq *req); +static VfsReq *hung_reads = NULL; void serial_init(void) { vfs_root_register("/com1", accept); } @@ -59,7 +59,7 @@ void serial_write(const char *buf, size_t len) { serial_putchar(buf[i]); } -static void accept(struct vfs_request *req) { +static void accept(VfsReq *req) { int ret; bool valid; switch (req->type) { diff --git a/src/kernel/arch/amd64/driver/util.c b/src/kernel/arch/amd64/driver/util.c index b2c33c6..957005c 100644 --- a/src/kernel/arch/amd64/driver/util.c +++ b/src/kernel/arch/amd64/driver/util.c @@ -5,7 +5,7 @@ #include <kernel/proc.h> #include <kernel/vfs/request.h> -int req_readcopy(struct vfs_request *req, const void *buf, size_t len) { +int req_readcopy(VfsReq *req, const void *buf, size_t len) { if (!req->caller) return -1; assert(req->type == VFSOP_READ); fs_normslice(&req->offset, &req->output.len, len, false); @@ -14,7 +14,7 @@ int req_readcopy(struct vfs_request *req, const void *buf, size_t len) { return req->output.len; } -void postqueue_join(struct vfs_request **queue, struct vfs_request *req) { +void postqueue_join(VfsReq **queue, VfsReq *req) { if (req->postqueue_next) panic_invalid_state(); @@ -23,16 +23,16 @@ void postqueue_join(struct vfs_request **queue, struct vfs_request *req) { *queue = req; } -bool postqueue_pop(struct vfs_request **queue, void (*accept)(struct vfs_request *)) { - struct vfs_request *req = *queue; +bool postqueue_pop(VfsReq **queue, void (*accept)(VfsReq *)) { + VfsReq *req = *queue; if (req == NULL) return false; *queue = req->postqueue_next; accept(req); return true; } -void postqueue_ringreadall(struct vfs_request **queue, ring_t *r) { - struct vfs_request *req; +void postqueue_ringreadall(VfsReq **queue, ring_t *r) { + VfsReq *req; char tmp[64]; size_t mlen = 0; if (ring_used(r) == 0) return; diff --git a/src/kernel/arch/amd64/driver/util.h b/src/kernel/arch/amd64/driver/util.h index 06ca672..5827fa9 100644 --- a/src/kernel/arch/amd64/driver/util.h +++ b/src/kernel/arch/amd64/driver/util.h @@ -1,10 +1,10 @@ #pragma once +#include <kernel/types.h> #include <shared/container/ring.h> #include <stdbool.h> #include <stddef.h> -struct vfs_request; -int req_readcopy(struct vfs_request *req, const void *buf, size_t len); +int req_readcopy(VfsReq *req, const void *buf, size_t len); /* compare request path. path MUST be a static string */ #define reqpathcmp(req, path) _reqpathcmp(req, ""path"", sizeof(path) - 1) @@ -13,9 +13,9 @@ int req_readcopy(struct vfs_request *req, const void *buf, size_t len); req->input.len == plen && \ memcmp(req->input.buf_kern, path, plen) == 0) -void postqueue_join(struct vfs_request **queue, struct vfs_request *req); -bool postqueue_pop(struct vfs_request **queue, void (*accept)(struct vfs_request *)); +void postqueue_join(VfsReq **queue, VfsReq *req); +bool postqueue_pop(VfsReq **queue, void (*accept)(VfsReq *)); /** If there are any pending read requests, and the ring buffer isn't empty, fulfill them * all with a single read. */ -void postqueue_ringreadall(struct vfs_request **queue, ring_t *r); +void postqueue_ringreadall(VfsReq **queue, ring_t *r); diff --git a/src/kernel/arch/amd64/driver/video.c b/src/kernel/arch/amd64/driver/video.c index 4cd6b0b..d7046b4 100644 --- a/src/kernel/arch/amd64/driver/video.c +++ b/src/kernel/arch/amd64/driver/video.c @@ -9,7 +9,7 @@ #include <shared/mem.h> #include <shared/printf.h> -static struct fb_info fb; +static GfxInfo fb; static char namebuf[64]; static size_t namelen; @@ -18,7 +18,7 @@ enum { H_FB, }; -static int handle(struct vfs_request *req) { +static int handle(VfsReq *req) { switch (req->type) { case VFSOP_OPEN: if (!req->input.kern) panic_invalid_state(); @@ -54,7 +54,7 @@ static int handle(struct vfs_request *req) { } } -static void accept(struct vfs_request *req) { +static void accept(VfsReq *req) { if (req->caller) { vfsreq_finish_short(req, handle(req)); } else { @@ -62,7 +62,7 @@ static void accept(struct vfs_request *req) { } } -void video_init(struct fb_info fb_) { +void video_init(GfxInfo fb_) { fb = fb_; snprintf(namebuf, sizeof namebuf, "%ux%ux%u", fb.width, fb.height, fb.bpp); namelen = strlen(namebuf); diff --git a/src/kernel/arch/amd64/driver/video.h b/src/kernel/arch/amd64/driver/video.h index dfc1710..e9dd8ae 100644 --- a/src/kernel/arch/amd64/driver/video.h +++ b/src/kernel/arch/amd64/driver/video.h @@ -1,7 +1,7 @@ #pragma once #include <stdint.h> -struct fb_info { +struct GfxInfo { char *b; uint32_t width, height; uint32_t pitch; /* width in bytes of a single scanline */ @@ -9,4 +9,4 @@ struct fb_info { uint8_t bpp; }; -void video_init(struct fb_info); +void video_init(GfxInfo); diff --git a/src/kernel/arch/amd64/interrupts/isr.c b/src/kernel/arch/amd64/interrupts/isr.c index 994519d..1059530 100644 --- a/src/kernel/arch/amd64/interrupts/isr.c +++ b/src/kernel/arch/amd64/interrupts/isr.c @@ -62,8 +62,8 @@ void isr_stage3(int interrupt, uint64_t *stackframe) { log_interrupt(interrupt, stackframe); cpu_halt(); } else { - process_kill(process_current, interrupt); - process_switch_any(); + proc_kill(proc_cur, interrupt); + proc_switch_any(); } } } diff --git a/src/kernel/arch/amd64/pagedir.c b/src/kernel/arch/amd64/pagedir.c index 4189774..9250a01 100644 --- a/src/kernel/arch/amd64/pagedir.c +++ b/src/kernel/arch/amd64/pagedir.c @@ -31,11 +31,11 @@ static __user void *addr_canonize(const __user void *addr) { } -struct pagedir *pagedir_new(void) { +Pagedir *pagedir_new(void) { return page_zalloc(1); } -void pagedir_free(struct pagedir *dir) { +void pagedir_free(Pagedir *dir) { for (int i = 0; i < 512; i++) { if (!dir->e[i].present) continue; assert(!dir->e[i].large); @@ -66,7 +66,7 @@ void pagedir_free(struct pagedir *dir) { } static pe_generic_t* -get_entry(struct pagedir *dir, const void __user *virt) { +get_entry(Pagedir *dir, const void __user *virt) { pe_generic_t *pml4e, *pdpte, *pde, *pte; const union virt_addr v = {.full = (void __user *)virt}; @@ -88,7 +88,7 @@ get_entry(struct pagedir *dir, const void __user *virt) { return pte; } -void pagedir_unmap_user(struct pagedir *dir, void __user *virt, size_t len) { +void pagedir_unmap_user(Pagedir *dir, void __user *virt, size_t len) { // TODO rewrite this const void __user *end = addr_canonize(virt + len); union virt_addr v = {.full = virt}; @@ -144,7 +144,7 @@ void pagedir_unmap_user(struct pagedir *dir, void __user *virt, size_t len) { } } -void pagedir_map(struct pagedir *dir, void __user *virt, void *phys, +void pagedir_map(Pagedir *dir, void __user *virt, void *phys, bool user, bool writeable) { pe_generic_t *pml4e, *pdpte, *pde, *pte; @@ -191,13 +191,13 @@ void pagedir_map(struct pagedir *dir, void __user *virt, void *phys, } extern void *pagedir_current; -void pagedir_switch(struct pagedir *dir) { +void pagedir_switch(Pagedir *dir) { pagedir_current = dir; } // creates a new pagedir with exact copies of the user pages -struct pagedir *pagedir_copy(const struct pagedir *pml4_old) { - struct pagedir *pml4_new = page_zalloc(1); +Pagedir *pagedir_copy(const Pagedir *pml4_old) { + Pagedir *pml4_new = page_zalloc(1); for (int i = 0; i < 512; i++) { if (!pml4_old->e[i].present) continue; @@ -239,12 +239,12 @@ struct pagedir *pagedir_copy(const struct pagedir *pml4_old) { return pml4_new; } -bool pagedir_iskern(struct pagedir *dir, const void __user *virt) { +bool pagedir_iskern(Pagedir *dir, const void __user *virt) { pe_generic_t *page = get_entry(dir, virt); return page && page->present && !page->user; } -void *pagedir_virt2phys(struct pagedir *dir, const void __user *virt, +void *pagedir_virt2phys(Pagedir *dir, const void __user *virt, bool user, bool writeable) { pe_generic_t *page = get_entry(dir, virt); @@ -255,7 +255,7 @@ void *pagedir_virt2phys(struct pagedir *dir, const void __user *virt, return addr_extract(*page) + ((uintptr_t)virt & PAGE_MASK); } -void __user *pagedir_findfree(struct pagedir *dir, char __user *start, size_t len) { +void __user *pagedir_findfree(Pagedir *dir, char __user *start, size_t len) { // TODO dogshit slow pe_generic_t *page; char __user *iter; diff --git a/src/kernel/arch/amd64/paging.h b/src/kernel/arch/amd64/paging.h index 156c0c5..70752b0 100644 --- a/src/kernel/arch/amd64/paging.h +++ b/src/kernel/arch/amd64/paging.h @@ -31,7 +31,7 @@ typedef union pe_generic_t { void *as_ptr; } pe_generic_t; // pageentry_generic -struct pagedir { /* on amd64 actually points to pml4. the name is like this for historical reasons */ +struct Pagedir { /* on amd64 actually points to pml4 */ pe_generic_t e[512]; } __attribute__((packed)); diff --git a/src/kernel/arch/amd64/registers.h b/src/kernel/arch/amd64/registers.h index b8f6248..5fd09c9 100644 --- a/src/kernel/arch/amd64/registers.h +++ b/src/kernel/arch/amd64/registers.h @@ -1,9 +1,9 @@ #pragma once -#include <camellia/types.h> +#include <kernel/types.h> #include <stdint.h> /* requires 16-byte alignment */ -struct registers { +struct CpuRegs { uint64_t r15, r14, r13, r12, r11, r10, r9, r8; uint64_t rdi, rsi; userptr_t rbp, rsp; @@ -12,7 +12,7 @@ struct registers { } __attribute__((__packed__)); // saves a return value according to the SysV ABI -static inline uint64_t regs_savereturn(struct registers *regs, uint64_t value) { +static inline uint64_t regs_savereturn(CpuRegs *regs, uint64_t value) { regs->rax = value; return value; } diff --git a/src/kernel/arch/amd64/sysenter.c b/src/kernel/arch/amd64/sysenter.c index 459247f..5a96e33 100644 --- a/src/kernel/arch/amd64/sysenter.c +++ b/src/kernel/arch/amd64/sysenter.c @@ -3,16 +3,16 @@ #include <kernel/arch/generic.h> #include <kernel/proc.h> -struct registers _sysexit_regs; +CpuRegs _sysexit_regs; -_Noreturn void sysexit(struct registers regs) { +_Noreturn void sysexit(CpuRegs regs) { _sysexit_regs = regs; _sysexit_real(); } _Noreturn void sysenter_stage2(void) { - struct registers *regs = &process_current->regs; + CpuRegs *regs = &proc_cur->regs; *regs = _sysexit_regs; _syscall(regs->rdi, regs->rsi, regs->rdx, regs->r10, regs->r8, regs->r9); - process_switch_any(); + proc_switch_any(); } diff --git a/src/kernel/arch/amd64/sysenter.h b/src/kernel/arch/amd64/sysenter.h index d1274de..03a9f45 100644 --- a/src/kernel/arch/amd64/sysenter.h +++ b/src/kernel/arch/amd64/sysenter.h @@ -1,7 +1,8 @@ #pragma once +#include <kernel/types.h> // sysenter.c -extern struct registers _sysexit_regs; +extern CpuRegs _sysexit_regs; _Noreturn void sysenter_stage2(void); // sysenter.s diff --git a/src/kernel/arch/amd64/time.c b/src/kernel/arch/amd64/time.c index d6e53dd..0e40521 100644 --- a/src/kernel/arch/amd64/time.c +++ b/src/kernel/arch/amd64/time.c @@ -3,7 +3,7 @@ #include <kernel/proc.h> static uint64_t uptime = 0, goal = ~0; -static struct process *scheduled = NULL; +static Proc *scheduled = NULL; uint64_t uptime_ms(void) { return uptime; } @@ -16,18 +16,18 @@ void pit_irq(void) { uptime++; if (uptime < goal) return; - struct process *p = scheduled; + Proc *p = scheduled; assert(p); scheduled = p->waits4timer.next; - process_transition(p, PS_RUNNING); + proc_setstate(p, PS_RUNNING); update_goal(); } -void timer_schedule(struct process *p, uint64_t time) { - process_transition(p, PS_WAITS4TIMER); +void timer_schedule(Proc *p, uint64_t time) { + proc_setstate(p, PS_WAITS4TIMER); p->waits4timer.goal = time; - struct process **slot = &scheduled; + Proc **slot = &scheduled; while (*slot && (*slot)->waits4timer.goal <= time) { assert((*slot)->state == PS_WAITS4TIMER); slot = &(*slot)->waits4timer.next; @@ -37,10 +37,10 @@ void timer_schedule(struct process *p, uint64_t time) { update_goal(); } -void timer_deschedule(struct process *p) { +void timer_deschedule(Proc *p) { assert(p->state == PS_WAITS4TIMER); - struct process **slot = &scheduled; + Proc **slot = &scheduled; while (*slot && *slot != p) slot = &(*slot)->waits4timer.next; assert(*slot); diff --git a/src/kernel/arch/generic.h b/src/kernel/arch/generic.h index 0cf4d50..647badc 100644 --- a/src/kernel/arch/generic.h +++ b/src/kernel/arch/generic.h @@ -1,10 +1,9 @@ #pragma once -#include <camellia/types.h> #include <kernel/arch/amd64/registers.h> +#include <kernel/types.h> #include <stdarg.h> #include <stdbool.h> #include <stddef.h> -struct process; // i have no idea where else to put it // some code assumes that it's a power of 2 @@ -25,28 +24,28 @@ void shutdown(void); void cpu_pause(void); uint64_t uptime_ms(void); -void timer_schedule(struct process *p, uint64_t time); -void timer_deschedule(struct process *p); +void timer_schedule(Proc *p, uint64_t time); +void timer_deschedule(Proc *p); // src/arch/i386/sysenter.s -_Noreturn void sysexit(struct registers); +_Noreturn void sysexit(CpuRegs); // all of those can allocate memory -struct pagedir *pagedir_new(void); -struct pagedir *pagedir_copy(const struct pagedir *orig); +Pagedir *pagedir_new(void); +Pagedir *pagedir_copy(const Pagedir *orig); -void pagedir_free(struct pagedir *); -void pagedir_unmap_user(struct pagedir *dir, void __user *virt, size_t len); -void pagedir_map(struct pagedir *dir, void __user *virt, void *phys, +void pagedir_free(Pagedir *); +void pagedir_unmap_user(Pagedir *dir, void __user *virt, size_t len); +void pagedir_map(Pagedir *dir, void __user *virt, void *phys, bool user, bool writeable); -bool pagedir_iskern(struct pagedir *, const void __user *virt); +bool pagedir_iskern(Pagedir *, const void __user *virt); -void __user *pagedir_findfree(struct pagedir *dir, char __user *start, size_t len); +void __user *pagedir_findfree(Pagedir *dir, char __user *start, size_t len); -void pagedir_switch(struct pagedir *); +void pagedir_switch(Pagedir *); // return 0 on failure -void *pagedir_virt2phys(struct pagedir *dir, const void __user *virt, +void *pagedir_virt2phys(Pagedir *dir, const void __user *virt, bool user, bool writeable); int kprintf(const char *fmt, ...); diff --git a/src/kernel/execbuf.c b/src/kernel/execbuf.c index 7170de2..8f7e22e 100644 --- a/src/kernel/execbuf.c +++ b/src/kernel/execbuf.c @@ -5,13 +5,13 @@ #include <kernel/panic.h> #include <shared/mem.h> -_Noreturn static void halt(struct process *proc) { +_Noreturn static void halt(Proc *proc) { kfree(proc->execbuf.buf); proc->execbuf.buf = NULL; - process_switch_any(); + proc_switch_any(); } -static void try_fetch(struct process *proc, uint64_t *buf, size_t amt) { +static void try_fetch(Proc *proc, uint64_t *buf, size_t amt) { size_t bytes = amt * sizeof(uint64_t); if (proc->execbuf.pos + bytes > proc->execbuf.len) halt(proc); @@ -19,10 +19,10 @@ static void try_fetch(struct process *proc, uint64_t *buf, size_t amt) { proc->execbuf.pos += bytes; } -_Noreturn void execbuf_run(struct process *proc) { +_Noreturn void execbuf_run(Proc *proc) { uint64_t buf[6]; - assert(proc == process_current); // idiotic, but needed because of _syscall. + assert(proc == proc_cur); // idiotic, but needed because of _syscall. assert(proc->state == PS_RUNNING); assert(proc->execbuf.buf); @@ -31,7 +31,7 @@ _Noreturn void execbuf_run(struct process *proc) { case EXECBUF_SYSCALL: try_fetch(proc, buf, 6); _syscall(buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); - process_switch_any(); + proc_switch_any(); case EXECBUF_JMP: try_fetch(proc, buf, 1); diff --git a/src/kernel/execbuf.h b/src/kernel/execbuf.h index 02ada92..e28cb76 100644 --- a/src/kernel/execbuf.h +++ b/src/kernel/execbuf.h @@ -1,4 +1,4 @@ #pragma once #include <kernel/proc.h> -_Noreturn void execbuf_run(struct process *proc); +_Noreturn void execbuf_run(Proc *proc); diff --git a/src/kernel/handle.c b/src/kernel/handle.c index fabe559..156be12 100644 --- a/src/kernel/handle.c +++ b/src/kernel/handle.c @@ -6,20 +6,20 @@ #include <kernel/vfs/request.h> #include <shared/mem.h> -struct handle *handle_init(enum handle_type type) { - struct handle *h = kzalloc(sizeof *h); +Handle *handle_init(enum handle_type type) { + Handle *h = kzalloc(sizeof *h); h->type = type; h->refcount = 1; return h; } -void handle_close(struct handle *h) { +void handle_close(Handle *h) { if (!h) return; assert(h->refcount > 0); if (--(h->refcount) > 0) return; if (h->type == HANDLE_FILE) { - vfsreq_create((struct vfs_request) { + vfsreq_create((VfsReq) { .type = VFSOP_CLOSE, .id = h->file_id, .caller = NULL, diff --git a/src/kernel/handle.h b/src/kernel/handle.h index 19d5953..21b4364 100644 --- a/src/kernel/handle.h +++ b/src/kernel/handle.h @@ -1,8 +1,5 @@ #pragma once - -enum handle_type; // forward declaration for proc.h - -#include <camellia/types.h> +#include <kernel/types.h> #include <kernel/vfs/mount.h> #include <kernel/vfs/request.h> #include <stddef.h> @@ -15,19 +12,19 @@ enum handle_type { HANDLE_FS_REQ, }; -struct handle { +struct Handle { enum handle_type type; - struct vfs_backend *backend; // HANDLE_FILE | HANDLE_FS_FRONT + VfsBackend *backend; // HANDLE_FILE | HANDLE_FS_FRONT void __user *file_id; // only applicable to HANDLE_FILE bool readable, writeable; /* HANDLE_FILE | HANDLE_PIPE */ - struct vfs_request *req; /* HANDLE_FS_REQ */ + VfsReq *req; /* HANDLE_FS_REQ */ struct { - struct process *queued; - struct handle *sister; // the other end, not included in refcount + Proc *queued; + Handle *sister; // the other end, not included in refcount } pipe; size_t refcount; }; -struct handle *handle_init(enum handle_type); -void handle_close(struct handle *); +Handle *handle_init(enum handle_type); +void handle_close(Handle *); diff --git a/src/kernel/mem/virt.c b/src/kernel/mem/virt.c index 8bf5e69..1ac6fbc 100644 --- a/src/kernel/mem/virt.c +++ b/src/kernel/mem/virt.c @@ -18,7 +18,7 @@ struct virt_iter { void __user *_virt; size_t _remaining; - struct pagedir *_pages; + Pagedir *_pages; bool _user; bool _writeable; }; @@ -30,12 +30,12 @@ struct virt_cpy_error { // unused /* if pages == NULL, creates an iterator over physical memory. */ static void virt_iter_new( struct virt_iter *iter, void __user *virt, size_t length, - struct pagedir *pages, bool user, bool writeable + Pagedir *pages, bool user, bool writeable ); static bool virt_iter_next(struct virt_iter *); static size_t virt_cpy( - struct pagedir *dest_pages, void __user *dest, - struct pagedir *src_pages, const void __user *src, + Pagedir *dest_pages, void __user *dest, + Pagedir *src_pages, const void __user *src, size_t length, struct virt_cpy_error *err ); @@ -43,7 +43,7 @@ static size_t virt_cpy( static void virt_iter_new( struct virt_iter *iter, void __user *virt, size_t length, - struct pagedir *pages, bool user, bool writeable + Pagedir *pages, bool user, bool writeable ) { iter->frag = NULL; iter->frag_len = 0; @@ -94,8 +94,8 @@ virt_iter_next(struct virt_iter *iter) static size_t virt_cpy( - struct pagedir *dest_pages, void __user *dest, - struct pagedir *src_pages, const void __user *src, + Pagedir *dest_pages, void __user *dest, + Pagedir *src_pages, const void __user *src, size_t length, struct virt_cpy_error *err ) { struct virt_iter dest_iter, src_iter; @@ -132,7 +132,7 @@ virt_cpy( } size_t -pcpy_to(struct process *p, __user void *dst, const void *src, size_t len) +pcpy_to(Proc *p, __user void *dst, const void *src, size_t len) { assert(p); if (!p->pages) return 0; @@ -140,7 +140,7 @@ pcpy_to(struct process *p, __user void *dst, const void *src, size_t len) } size_t -pcpy_from(struct process *p, void *dst, const __user void *src, size_t len) +pcpy_from(Proc *p, void *dst, const __user void *src, size_t len) { assert(p); if (!p->pages) return 0; @@ -149,8 +149,8 @@ pcpy_from(struct process *p, void *dst, const __user void *src, size_t len) size_t pcpy_bi( - struct process *dstp, __user void *dst, - struct process *srcp, const __user void *src, + Proc *dstp, __user void *dst, + Proc *srcp, const __user void *src, size_t len ) { assert(dstp && srcp); diff --git a/src/kernel/mem/virt.h b/src/kernel/mem/virt.h index fc35078..7c9380e 100644 --- a/src/kernel/mem/virt.h +++ b/src/kernel/mem/virt.h @@ -1,14 +1,12 @@ // move this to proc.h, maybe? #pragma once -#include <camellia/types.h> +#include <kernel/types.h> #include <stddef.h> -struct process; - -size_t pcpy_to(struct process *p, __user void *dst, const void *src, size_t len); -size_t pcpy_from(struct process *p, void *dst, const __user void *src, size_t len); +size_t pcpy_to(Proc *p, __user void *dst, const void *src, size_t len); +size_t pcpy_from(Proc *p, void *dst, const __user void *src, size_t len); size_t pcpy_bi( - struct process *dstp, __user void *dst, - struct process *srcp, const __user void *src, + Proc *dstp, __user void *dst, + Proc *srcp, const __user void *src, size_t len ); diff --git a/src/kernel/pipe.c b/src/kernel/pipe.c index 29e68e2..3ac52d3 100644 --- a/src/kernel/pipe.c +++ b/src/kernel/pipe.c @@ -3,9 +3,9 @@ #include <kernel/pipe.h> #include <kernel/util.h> -static void pipe_trytransfer(struct handle *h); +static void pipe_trytransfer(Handle *h); -void pipe_joinqueue(struct handle *h, struct process *proc, void __user *pbuf, size_t pbuflen) { +void pipe_joinqueue(Handle *h, Proc *proc, void __user *pbuf, size_t pbuflen) { assert(h && h->type == HANDLE_PIPE); assert(h->readable ^ h->writeable); if (!h->pipe.sister) { @@ -13,13 +13,13 @@ void pipe_joinqueue(struct handle *h, struct process *proc, void __user *pbuf, s return; } - struct process **slot = &h->pipe.queued; + Proc **slot = &h->pipe.queued; while (*slot) { assert((*slot)->state == PS_WAITS4PIPE); slot = &((*slot)->waits4pipe.next); } - process_transition(proc, PS_WAITS4PIPE); + proc_setstate(proc, PS_WAITS4PIPE); *slot = proc; proc->waits4pipe.pipe = h; proc->waits4pipe.buf = pbuf; @@ -28,8 +28,8 @@ void pipe_joinqueue(struct handle *h, struct process *proc, void __user *pbuf, s pipe_trytransfer(h); } -static void pipe_trytransfer(struct handle *h) { - struct process *rdr, *wtr; +static void pipe_trytransfer(Handle *h) { + Proc *rdr, *wtr; int len; assert(h && h->type == HANDLE_PIPE); assert(h->readable ^ h->writeable); @@ -52,17 +52,17 @@ static void pipe_trytransfer(struct handle *h) { ); h->pipe.queued = h->pipe.queued->waits4pipe.next; h->pipe.sister->pipe.queued = h->pipe.sister->pipe.queued->waits4pipe.next; - process_transition(rdr, PS_RUNNING); - process_transition(wtr, PS_RUNNING); + proc_setstate(rdr, PS_RUNNING); + proc_setstate(wtr, PS_RUNNING); regs_savereturn(&rdr->regs, len); regs_savereturn(&wtr->regs, len); } -void pipe_invalidate_end(struct handle *h) { - struct process *p = h->pipe.queued; +void pipe_invalidate_end(Handle *h) { + Proc *p = h->pipe.queued; while (p) { assert(p->state == PS_WAITS4PIPE); - process_transition(p, PS_RUNNING); + proc_setstate(p, PS_RUNNING); regs_savereturn(&p->regs, -1); p = p->waits4pipe.next; } diff --git a/src/kernel/pipe.h b/src/kernel/pipe.h index bcdfb86..24414f8 100644 --- a/src/kernel/pipe.h +++ b/src/kernel/pipe.h @@ -3,6 +3,6 @@ #include <stdbool.h> /* eventually transitions to PS_RUNNING */ -void pipe_joinqueue(struct handle *h, struct process *proc, void __user *pbuf, size_t pbuflen); +void pipe_joinqueue(Handle *h, Proc *proc, void __user *pbuf, size_t pbuflen); -void pipe_invalidate_end(struct handle *h); +void pipe_invalidate_end(Handle *h); diff --git a/src/kernel/proc.c b/src/kernel/proc.c index 109316e..93fef1a 100755 --- a/src/kernel/proc.c +++ b/src/kernel/proc.c @@ -11,46 +11,46 @@ #include <shared/mem.h> #include <stdint.h> -static struct process *process_first = NULL; -static struct process *process_forgotten = NULL; /* linked list */ -struct process *process_current; +static Proc *proc_first = NULL; +static Proc *proc_forgotten = NULL; /* linked list */ +Proc *proc_cur; static uint32_t next_pid = 1; /** Removes a process from the process tree. */ -static void process_forget(struct process *p); -static void process_free_forgotten(void); -static _Noreturn void process_switch(struct process *proc); - - -struct process *process_seed(void *data, size_t datalen) { - assert(!process_first); - process_first = kzalloc(sizeof *process_first); - process_first->state = PS_RUNNING; - process_first->pages = pagedir_new(); - process_first->mount = vfs_mount_seed(); - process_first->globalid = next_pid++; - process_first->cid = 1; - process_first->nextcid = 1; - process_first->_handles = kzalloc(sizeof(struct handle) * HANDLE_MAX); +static void proc_forget(Proc *p); +static void proc_free_forgotten(void); +static _Noreturn void proc_switch(Proc *proc); + + +Proc *proc_seed(void *data, size_t datalen) { + assert(!proc_first); + proc_first = kzalloc(sizeof *proc_first); + proc_first->state = PS_RUNNING; + proc_first->pages = pagedir_new(); + proc_first->mount = vfs_mount_seed(); + proc_first->globalid = next_pid++; + proc_first->cid = 1; + proc_first->nextcid = 1; + proc_first->_handles = kzalloc(sizeof(Handle) * HANDLE_MAX); // map .shared extern char _shared_len; for (size_t p = 0; p < (size_t)&_shared_len; p += PAGE_SIZE) - pagedir_map(process_first->pages, (userptr_t)p, (void*)p, false, true); + pagedir_map(proc_first->pages, (userptr_t)p, (void*)p, false, true); // map the init module as rw void __user *init_base = (userptr_t)0x200000; for (uintptr_t off = 0; off < datalen; off += PAGE_SIZE) - pagedir_map(process_first->pages, init_base + off, data + off, true, true); - process_first->regs.rcx = (uintptr_t)init_base; // SYSRET jumps to %rcx + pagedir_map(proc_first->pages, init_base + off, data + off, true, true); + proc_first->regs.rcx = (uintptr_t)init_base; // SYSRET jumps to %rcx - return process_first; + return proc_first; } -struct process *process_fork(struct process *parent, int flags) { - struct process *child = kzalloc(sizeof *child); +Proc *proc_fork(Proc *parent, int flags) { + Proc *child = kzalloc(sizeof *child); if (flags & FORK_SHAREMEM) { if (!parent->pages_refcount) { @@ -100,8 +100,8 @@ struct process *process_fork(struct process *parent, int flags) { child->handles_refcount = parent->handles_refcount; child->_handles = parent->_handles; } else { - child->_handles = kzalloc(sizeof(struct handle) * HANDLE_MAX); - for (handle_t h = 0; h < HANDLE_MAX; h++) { + child->_handles = kzalloc(sizeof(Handle) * HANDLE_MAX); + for (hid_t h = 0; h < HANDLE_MAX; h++) { child->_handles[h] = parent->_handles[h]; if (child->_handles[h]) child->_handles[h]->refcount++; @@ -123,7 +123,7 @@ static bool unref(uint64_t *refcount) { return false; } -void process_kill(struct process *p, int ret) { +void proc_kill(Proc *p, int ret) { if (proc_alive(p)) { if (p->controlled) { // TODO vfs_backend_user_handlerdown @@ -145,7 +145,7 @@ void process_kill(struct process *p, int ret) { } if (p->state == PS_WAITS4PIPE) { - struct process **iter = &p->waits4pipe.pipe->pipe.queued; + Proc **iter = &p->waits4pipe.pipe->pipe.queued; while (*iter && *iter != p) { assert((*iter)->state == PS_WAITS4PIPE); iter = &(*iter)->waits4pipe.next; @@ -159,8 +159,8 @@ void process_kill(struct process *p, int ret) { } if (unref(p->handles_refcount)) { - for (handle_t hid = 0; hid < HANDLE_MAX; hid++) - process_handle_close(p, hid); + for (hid_t hid = 0; hid < HANDLE_MAX; hid++) + proc_handle_close(p, hid); kfree(p->_handles); } p->_handles = NULL; @@ -168,14 +168,14 @@ void process_kill(struct process *p, int ret) { vfs_mount_remref(p->mount); p->mount = NULL; - process_transition(p, PS_DYING); + proc_setstate(p, PS_DYING); p->death_msg = ret; /* tombstone TOREAP children */ - for (struct process *it = p->child; it; ) { - struct process *sibling = it->sibling; + for (Proc *it = p->child; it; ) { + Proc *sibling = it->sibling; if (it->state == PS_TOREAP) { - process_tryreap(it); + proc_tryreap(it); } it = sibling; } @@ -193,45 +193,45 @@ void process_kill(struct process *p, int ret) { if (p->state == PS_DYING) { if (p->parent && proc_alive(p->parent)) { - process_transition(p, PS_TOREAP); + proc_setstate(p, PS_TOREAP); } else { - process_transition(p, PS_TOMBSTONE); + proc_setstate(p, PS_TOMBSTONE); } } - if (p == process_first && p->child) { + if (p == proc_first && p->child) { _panic("init killed prematurely"); } - process_tryreap(p); + proc_tryreap(p); - if (p == process_first) { - process_free_forgotten(); + if (p == proc_first) { + proc_free_forgotten(); shutdown(); } } -void process_filicide(struct process *parent, int ret) { +void proc_filicide(Proc *parent, int ret) { /* Kill deeper descendants. */ - struct process *child, *child2; + Proc *child, *child2; for (child = parent->child; child; child = child2) { child2 = child->sibling; // O(n^2), but doable in linear time while (child->child) { - struct process *p = child->child; + Proc *p = child->child; while (p->child) p = p->child; p->noreap = true; - process_kill(p, ret); + proc_kill(p, ret); } if (proc_alive(child)) { - process_kill(child, ret); + proc_kill(child, ret); } child = NULL; } } -void process_tryreap(struct process *dead) { - struct process *parent; +void proc_tryreap(Proc *dead) { + Proc *parent; assert(dead && !proc_alive(dead)); parent = dead->parent; if (parent) assert(parent->child); @@ -243,20 +243,20 @@ void process_tryreap(struct process *dead) { return; /* don't reap yet */ } regs_savereturn(&parent->regs, dead->death_msg); - process_transition(parent, PS_RUNNING); + proc_setstate(parent, PS_RUNNING); } /* can't be reaped anymore */ - process_transition(dead, PS_TOMBSTONE); + proc_setstate(dead, PS_TOMBSTONE); dead->noreap = true; } assert(dead->state == PS_TOMBSTONE); - for (struct process *p = dead->child; p; p = p->sibling) { + for (Proc *p = dead->child; p; p = p->sibling) { assert(p->state != PS_TOREAP); } if (dead->child) { - struct process *p = dead->child; + Proc *p = dead->child; while (p->child) p = p->child; if (p->state == PS_TOREAP) { assert(proc_alive(p->parent)); @@ -269,16 +269,16 @@ void process_tryreap(struct process *dead) { handle_close(dead->specialh.procfs); assert(dead->refcount == 0); if (parent) { /* not applicable to init */ - process_forget(dead); + proc_forget(dead); // TODO force gcc to optimize the tail call here if (!proc_alive(parent)) { - process_tryreap(parent); + proc_tryreap(parent); } } } -void process_intr(struct process *p) { +void proc_intr(Proc *p) { if (!p->intr_fn) return; /* save old rsp,rip */ @@ -294,7 +294,7 @@ void process_intr(struct process *p) { } /** Removes a process from the process tree. */ -static void process_forget(struct process *p) { +static void proc_forget(Proc *p) { assert(p->parent); assert(p->parent->child); assert(!p->child); @@ -303,7 +303,7 @@ static void process_forget(struct process *p) { p->parent->child = p->sibling; } else { // this would be simpler if siblings were a doubly linked list - struct process *prev = p->parent->child; + Proc *prev = p->parent->child; while (prev->sibling != p) { prev = prev->sibling; assert(prev); @@ -312,24 +312,24 @@ static void process_forget(struct process *p) { } p->parent = NULL; - p->sibling = process_forgotten; - process_forgotten = p; - process_transition(p, PS_FORGOTTEN); + p->sibling = proc_forgotten; + proc_forgotten = p; + proc_setstate(p, PS_FORGOTTEN); } -static void process_free_forgotten(void) { - while (process_forgotten) { - struct process *p = process_forgotten; - process_forgotten = p->sibling; +static void proc_free_forgotten(void) { + while (proc_forgotten) { + Proc *p = proc_forgotten; + proc_forgotten = p->sibling; - process_transition(p, PS_FREED); + proc_setstate(p, PS_FREED); kfree(p); } } -static _Noreturn void process_switch(struct process *proc) { +static _Noreturn void proc_switch(Proc *proc) { assert(proc->state == PS_RUNNING); - process_current = proc; + proc_cur = proc; pagedir_switch(proc->pages); if (proc->execbuf.buf) execbuf_run(proc); @@ -337,25 +337,25 @@ static _Noreturn void process_switch(struct process *proc) { sysexit(proc->regs); } -_Noreturn void process_switch_any(void) { +_Noreturn void proc_switch_any(void) { /* At this point there will be no leftover pointers to forgotten * processes on the stack, so it's safe to free them. */ - process_free_forgotten(); + proc_free_forgotten(); for (;;) { - if (process_current && process_current->state == PS_RUNNING) - process_switch(process_current); + if (proc_cur && proc_cur->state == PS_RUNNING) + proc_switch(proc_cur); - for (struct process *p = process_first; p; p = process_next(p, NULL)) { + for (Proc *p = proc_first; p; p = proc_next(p, NULL)) { if (p->state == PS_RUNNING) - process_switch(p); + proc_switch(p); } cpu_pause(); } } -struct process *process_next(struct process *p, struct process *root) { +Proc *proc_next(Proc *p, Proc *root) { /* depth-first search, the order is: * 1 * / \ @@ -376,17 +376,17 @@ struct process *process_next(struct process *p, struct process *root) { return p->sibling; } -handle_t process_find_free_handle(struct process *proc, handle_t start_at) { - for (handle_t hid = start_at; hid < HANDLE_MAX; hid++) { +hid_t proc_find_free_handle(Proc *proc, hid_t start_at) { + for (hid_t hid = start_at; hid < HANDLE_MAX; hid++) { if (proc->_handles[hid] == NULL) return hid; } return -1; } -struct handle *process_handle_get(struct process *p, handle_t id) { +Handle *proc_handle_get(Proc *p, hid_t id) { if (id == HANDLE_NULLFS) { - static struct handle h = (struct handle){ + static Handle h = (Handle){ .type = HANDLE_FS_FRONT, .backend = NULL, .refcount = 2, /* never free */ @@ -394,8 +394,8 @@ struct handle *process_handle_get(struct process *p, handle_t id) { return &h; } else if (id == HANDLE_PROCFS) { if (!p->specialh.procfs) { - struct handle *h = kmalloc(sizeof *h); - *h = (struct handle){ + Handle *h = kmalloc(sizeof *h); + *h = (Handle){ .type = HANDLE_FS_FRONT, .backend = procfs_backend(p), .refcount = 1, @@ -410,19 +410,19 @@ struct handle *process_handle_get(struct process *p, handle_t id) { } } -handle_t process_handle_init(struct process *p, enum handle_type type, struct handle **hs) { - handle_t hid = process_find_free_handle(p, 1); +hid_t proc_handle_init(Proc *p, enum handle_type type, Handle **hs) { + hid_t hid = proc_find_free_handle(p, 1); if (hid < 0) return -1; p->_handles[hid] = handle_init(type); if (hs) *hs = p->_handles[hid]; return hid; } -handle_t process_handle_dup(struct process *p, handle_t from, handle_t to) { - struct handle *fromh, **toh; +hid_t proc_handle_dup(Proc *p, hid_t from, hid_t to) { + Handle *fromh, **toh; if (to < 0) { - to = process_find_free_handle(p, 0); + to = proc_find_free_handle(p, 0); if (to < 0) return -EMFILE; } else if (to >= HANDLE_MAX) { return -EBADF; @@ -430,7 +430,7 @@ handle_t process_handle_dup(struct process *p, handle_t from, handle_t to) { if (to == from) return to; toh = &p->_handles[to]; - fromh = process_handle_get(p, from); + fromh = proc_handle_get(p, from); if (*toh) handle_close(*toh); *toh = fromh; @@ -439,18 +439,18 @@ handle_t process_handle_dup(struct process *p, handle_t from, handle_t to) { return to; } -struct handle *process_handle_take(struct process *p, handle_t hid) { +Handle *proc_hid_take(Proc *p, hid_t hid) { if (hid < 0 || hid >= HANDLE_MAX) { - return process_handle_get(p, hid); + return proc_handle_get(p, hid); } - struct handle *h = p->_handles[hid]; + Handle *h = p->_handles[hid]; p->_handles[hid] = NULL; return h; } -handle_t process_handle_put(struct process *p, struct handle *h) { +hid_t proc_handle_put(Proc *p, Handle *h) { assert(h); - handle_t hid = process_find_free_handle(p, 1); + hid_t hid = proc_find_free_handle(p, 1); if (hid < 0) { handle_close(h); return hid; @@ -459,7 +459,7 @@ handle_t process_handle_put(struct process *p, struct handle *h) { return hid; } -void process_transition(struct process *p, enum process_state state) { +void proc_setstate(Proc *p, enum proc_state state) { assert(p->state != PS_FREED); if (state == PS_FREED) { assert(p->state == PS_FORGOTTEN); @@ -471,7 +471,7 @@ void process_transition(struct process *p, enum process_state state) { assert(p->state == PS_DYING); assert(!p->parent || proc_alive(p->parent)); - for (struct process *it = p->child; it; it = it->sibling) { + for (Proc *it = p->child; it; it = it->sibling) { assert(p->state != PS_TOREAP); } } else if (state != PS_RUNNING && state != PS_DYING) { diff --git a/src/kernel/proc.h b/src/kernel/proc.h index 041dbd0..5120778 100644 --- a/src/kernel/proc.h +++ b/src/kernel/proc.h @@ -1,15 +1,15 @@ #pragma once #include <kernel/arch/generic.h> #include <kernel/handle.h> +#include <kernel/types.h> #include <stdbool.h> -struct vfs_mount; #define HANDLE_MAX 16 -/* legal transitions described by process_transition */ -enum process_state { +/* legal transitions described by proc_setstate */ +enum proc_state { PS_RUNNING, - PS_DYING, /* during process_kill - mostly treated as alive */ + PS_DYING, /* during proc_kill - mostly treated as alive */ PS_TOREAP, /* return message not collected */ PS_TOMBSTONE, /* fully dead, supports alive children */ /* not in the process tree, waits for free. @@ -33,15 +33,15 @@ enum process_state { && p->state != PS_FREED \ ) -struct process { - struct pagedir *pages; +struct Proc { + Pagedir *pages; /* if NULL, refcount == 1. kmalloc'd */ uint64_t *pages_refcount; - struct registers regs; - struct process *sibling, *child, *parent; + CpuRegs regs; + Proc *sibling, *child, *parent; - enum process_state state; + enum proc_state state; union { /* saved value, meaning depends on .state */ int death_msg; // PS_DEAD struct { @@ -50,23 +50,23 @@ struct process { struct ufs_request __user *res; } awaited_req; // PS_WAITS4REQUEST struct { - struct handle *pipe; + Handle *pipe; char __user *buf; size_t len; - struct process *next; + Proc *next; } waits4pipe; struct { /* managed by timer_schedule */ uint64_t goal; - struct process *next; + Proc *next; } waits4timer; }; - struct vfs_mount *mount; - struct handle **_handles; /* points to struct handle *[HANDLE_MAX] */ + VfsMount *mount; + Handle **_handles; /* points to Handle *[HANDLE_MAX] */ uint64_t *handles_refcount; /* works just like pages_refcount */ struct { - struct handle *procfs; + Handle *procfs; } specialh; uint32_t cid; /* child id. unique amongst all of this process' siblings */ @@ -76,10 +76,10 @@ struct process { bool noreap; /* allocated once, the requests from WAITS4FS get stored here */ - struct vfs_request *reqslot; + VfsReq *reqslot; /* vfs_backend controlled (not exclusively) by this process */ - struct vfs_backend *controlled; + VfsBackend *controlled; /* interrupt handler */ void __user *intr_fn; @@ -91,40 +91,40 @@ struct process { } execbuf; }; -extern struct process *process_current; +extern Proc *proc_cur; /** Creates the root process. */ -struct process *process_seed(void *data, size_t datalen); -struct process *process_fork(struct process *parent, int flags); +Proc *proc_seed(void *data, size_t datalen); +Proc *proc_fork(Proc *parent, int flags); -void process_kill(struct process *proc, int ret); +void proc_kill(Proc *proc, int ret); /** Kills all descendants. */ -void process_filicide(struct process *proc, int ret); +void proc_filicide(Proc *proc, int ret); /** Tries to reap a dead process / free a tombstone. */ -void process_tryreap(struct process *dead); +void proc_tryreap(Proc *dead); -void process_intr(struct process *proc); +void proc_intr(Proc *proc); /** Switches execution to any running process. */ -_Noreturn void process_switch_any(void); +_Noreturn void proc_switch_any(void); /** Used for iterating over all processes */ -struct process *process_next(struct process *p, struct process *root); +Proc *proc_next(Proc *p, Proc *root); -handle_t process_find_free_handle(struct process *proc, handle_t start_at); -struct handle *process_handle_get(struct process *, handle_t); -handle_t process_handle_init(struct process *, enum handle_type, struct handle **); -handle_t process_handle_dup(struct process *p, handle_t from, handle_t to); -static inline void process_handle_close(struct process *p, handle_t hid) { +hid_t proc_find_free_handle(Proc *proc, hid_t start_at); +Handle *proc_handle_get(Proc *, hid_t); +hid_t proc_handle_init(Proc *, enum handle_type, Handle **); +hid_t proc_handle_dup(Proc *p, hid_t from, hid_t to); +static inline void proc_handle_close(Proc *p, hid_t hid) { // TODO test - process_handle_dup(p, -1, hid); + proc_handle_dup(p, -1, hid); } /* Gets a handle and removes the process' reference to it, without decreasing the refcount. - * Meant to be used together with process_handle_put. */ -struct handle *process_handle_take(struct process *, handle_t); + * Meant to be used together with proc_handle_put. */ +Handle *proc_hid_take(Proc *, hid_t); /* Put a handle in a process, taking the ownership away from the caller. * Doesn't increase the refcount on success, decreases it on failure. */ -handle_t process_handle_put(struct process *, struct handle *); +hid_t proc_handle_put(Proc *, Handle *); -void process_transition(struct process *, enum process_state); +void proc_setstate(Proc *, enum proc_state); diff --git a/src/kernel/ring.c b/src/kernel/ring.c index 6c03333..2cb6961 100644 --- a/src/kernel/ring.c +++ b/src/kernel/ring.c @@ -1,7 +1,7 @@ #include <kernel/mem/virt.h> #include <kernel/ring.h> -size_t ring_to_virt(ring_t *r, struct process *proc, void __user *ubuf, size_t max) { +size_t ring_to_virt(ring_t *r, Proc *proc, void __user *ubuf, size_t max) { char tmp[32]; if (max > sizeof tmp) max = sizeof tmp; max = ring_get(r, tmp, max); diff --git a/src/kernel/ring.h b/src/kernel/ring.h index 15f4682..89770d0 100644 --- a/src/kernel/ring.h +++ b/src/kernel/ring.h @@ -1,6 +1,6 @@ #pragma once // TODO merge into driver/util.h +#include <kernel/types.h> #include <shared/container/ring.h> -struct pagedir; -size_t ring_to_virt(ring_t *r, struct process *proc, void __user *ubuf, size_t max); +size_t ring_to_virt(ring_t *r, Proc *proc, void __user *ubuf, size_t max); diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index 4b03ef4..1ab2efd 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -13,50 +13,50 @@ #include <stdint.h> #define SYSCALL_RETURN(val) do { \ - assert(process_current->state == PS_RUNNING); \ - regs_savereturn(&process_current->regs, (long)(val)); \ + assert(proc_cur->state == PS_RUNNING); \ + regs_savereturn(&proc_cur->regs, (long)(val)); \ return 0; \ } while (0) -_Noreturn void _syscall_exit(long ret) { - process_kill(process_current, ret); - process_switch_any(); +_Noreturn void _sys_exit(long ret) { + proc_kill(proc_cur, ret); + proc_switch_any(); } -long _syscall_await(void) { +long _sys_await(void) { bool has_children = false; - process_transition(process_current, PS_WAITS4CHILDDEATH); + proc_setstate(proc_cur, PS_WAITS4CHILDDEATH); - for (struct process *iter = process_current->child; + for (Proc *iter = proc_cur->child; iter; iter = iter->sibling) { if (iter->noreap) continue; has_children = true; if (iter->state == PS_TOREAP) { - process_tryreap(iter); + proc_tryreap(iter); return 0; // dummy } } if (!has_children) { - process_transition(process_current, PS_RUNNING); + proc_setstate(proc_cur, PS_RUNNING); SYSCALL_RETURN(~0); // TODO errno } return 0; // dummy } -long _syscall_fork(int flags, handle_t __user *fs_front) { - struct process *child; +long _sys_fork(int flags, hid_t __user *fs_front) { + Proc *child; - child = process_fork(process_current, flags); + child = proc_fork(proc_cur, flags); regs_savereturn(&child->regs, 0); if (flags & FORK_NEWFS) { - struct handle *h; - handle_t hid = process_handle_init(process_current, HANDLE_FS_FRONT, &h); + Handle *h; + hid_t hid = proc_handle_init(proc_cur, HANDLE_FS_FRONT, &h); if (hid < 0) { child->noreap = true; - process_kill(child, -EMFILE); + proc_kill(child, -EMFILE); SYSCALL_RETURN(-EMFILE); } @@ -72,14 +72,14 @@ long _syscall_fork(int flags, handle_t __user *fs_front) { /* failure ignored. if you pass an invalid pointer to this function, * you just don't receive the handle. you'll probably segfault * trying to access it anyways */ - pcpy_to(process_current, fs_front, &hid, sizeof hid); + pcpy_to(proc_cur, fs_front, &hid, sizeof hid); } } SYSCALL_RETURN(child->cid); } -handle_t _syscall_open(const char __user *path, long len, int flags) { - struct vfs_mount *mount; +hid_t _sys_open(const char __user *path, long len, int flags) { + VfsMount *mount; char *path_buf = NULL; if (flags & ~(OPEN_RW | OPEN_CREATE)) SYSCALL_RETURN(-ENOSYS); @@ -90,14 +90,14 @@ handle_t _syscall_open(const char __user *path, long len, int flags) { * handles in the meantime anyways, or free some up. */ path_buf = kmalloc(len); - if (pcpy_from(process_current, path_buf, path, len) < (size_t)len) { + if (pcpy_from(proc_cur, path_buf, path, len) < (size_t)len) { goto fail; } len = path_simplify(path_buf, path_buf, len); if (len == 0) goto fail; - mount = vfs_mount_resolve(process_current->mount, path_buf, len); + mount = vfs_mount_resolve(proc_cur->mount, path_buf, len); if (!mount) goto fail; if (mount->prefix_len > 0) { // strip prefix @@ -107,14 +107,14 @@ handle_t _syscall_open(const char __user *path, long len, int flags) { memcpy(path_buf, path_buf + mount->prefix_len, len); } - vfsreq_create((struct vfs_request) { + vfsreq_create((VfsReq) { .type = VFSOP_OPEN, .input = { .kern = true, .buf_kern = path_buf, .len = len, }, - .caller = process_current, + .caller = proc_cur, .backend = mount->backend, .flags = flags, }); @@ -124,16 +124,16 @@ fail: SYSCALL_RETURN(-1); } -long _syscall_mount(handle_t hid, const char __user *path, long len) { - struct vfs_mount *mount = NULL; - struct vfs_backend *backend = NULL; +long _sys_mount(hid_t hid, const char __user *path, long len) { + VfsMount *mount = NULL; + VfsBackend *backend = NULL; char *path_buf = NULL; if (PATH_MAX < len) SYSCALL_RETURN(-1); path_buf = kmalloc(len); - if (pcpy_from(process_current, path_buf, path, len) < (size_t)len) { + if (pcpy_from(proc_cur, path_buf, path, len) < (size_t)len) { goto fail; } @@ -147,7 +147,7 @@ long _syscall_mount(handle_t hid, const char __user *path, long len) { len--; } - struct handle *handle = process_handle_get(process_current, hid); + Handle *handle = proc_handle_get(proc_cur, hid); if (!handle || handle->type != HANDLE_FS_FRONT) goto fail; backend = handle->backend; @@ -159,13 +159,13 @@ long _syscall_mount(handle_t hid, const char __user *path, long len) { // append to mount list // TODO move to kernel/vfs/mount.c mount = kmalloc(sizeof *mount); - mount->prev = process_current->mount; + mount->prev = proc_cur->mount; mount->prefix = path_buf; mount->prefix_owned = true; mount->prefix_len = len; mount->backend = backend; mount->refs = 1; - process_current->mount = mount; + proc_cur->mount = mount; kmalloc_sanity(mount); kmalloc_sanity(mount->prefix); @@ -177,19 +177,19 @@ fail: SYSCALL_RETURN(-1); } -handle_t _syscall_dup(handle_t from, handle_t to, int flags) { +hid_t _sys_dup(hid_t from, hid_t to, int flags) { if (flags != 0) SYSCALL_RETURN(-ENOSYS); - SYSCALL_RETURN(process_handle_dup(process_current, from, to)); + SYSCALL_RETURN(proc_handle_dup(proc_cur, from, to)); } static long simple_vfsop( - enum vfs_operation vfsop, handle_t hid, void __user *buf, + enum vfs_op vfsop, hid_t hid, void __user *buf, size_t len, long offset, int flags) { assert(vfsop == VFSOP_READ || vfsop == VFSOP_WRITE || vfsop == VFSOP_GETSIZE); - struct handle *h = process_handle_get(process_current, hid); + Handle *h = proc_handle_get(proc_cur, hid); if (!h) SYSCALL_RETURN(-EBADF); // TODO those checks really need some comprehensive tests if (vfsop == VFSOP_READ && !h->readable) @@ -198,11 +198,11 @@ static long simple_vfsop( SYSCALL_RETURN(-EACCES); if (h->type == HANDLE_FILE) { - struct vfs_request req = (struct vfs_request){ + VfsReq req = (VfsReq){ .type = vfsop, .backend = h->backend, .id = h->file_id, - .caller = process_current, + .caller = proc_cur, .offset = offset, .flags = flags, }; @@ -218,60 +218,60 @@ static long simple_vfsop( } else if (h->type == HANDLE_PIPE) { if (vfsop == VFSOP_READ || vfsop == VFSOP_WRITE) { /* already checked if this is the correct pipe end */ - pipe_joinqueue(h, process_current, buf, len); + pipe_joinqueue(h, proc_cur, buf, len); } else SYSCALL_RETURN(-ENOSYS); } else SYSCALL_RETURN(-ENOSYS); return 0; } -long _syscall_read(handle_t hid, void __user *buf, size_t len, long offset) { +long _sys_read(hid_t hid, void __user *buf, size_t len, long offset) { simple_vfsop(VFSOP_READ, hid, buf, len, offset, 0); return 0; } -long _syscall_write(handle_t hid, const void __user *buf, size_t len, long offset, int flags) { +long _sys_write(hid_t hid, const void __user *buf, size_t len, long offset, int flags) { if (flags & ~(WRITE_TRUNCATE)) SYSCALL_RETURN(-ENOSYS); simple_vfsop(VFSOP_WRITE, hid, (userptr_t)buf, len, offset, flags); return 0; } -long _syscall_getsize(handle_t hid) { +long _sys_getsize(hid_t hid) { simple_vfsop(VFSOP_GETSIZE, hid, NULL, 0, 0, 0); return 0; } -long _syscall_remove(handle_t hid) { - struct handle *h = process_handle_get(process_current, hid); +long _sys_remove(hid_t hid) { + Handle *h = proc_handle_get(proc_cur, hid); if (!h) SYSCALL_RETURN(-EBADF); if (h->type != HANDLE_FILE) { - process_handle_close(process_current, hid); + proc_handle_close(proc_cur, hid); SYSCALL_RETURN(-ENOSYS); } if (!h->writeable) { - process_handle_close(process_current, hid); + proc_handle_close(proc_cur, hid); SYSCALL_RETURN(-EACCES); } - vfsreq_create((struct vfs_request) { + vfsreq_create((VfsReq) { .type = VFSOP_REMOVE, .id = h->file_id, - .caller = process_current, + .caller = proc_cur, .backend = h->backend, }); - process_handle_close(process_current, hid); + proc_handle_close(proc_cur, hid); return -1; // dummy } -long _syscall_close(handle_t hid) { - if (!process_handle_get(process_current, hid)) { +long _sys_close(hid_t hid) { + if (!proc_handle_get(proc_cur, hid)) { SYSCALL_RETURN(-EBADF); } - process_handle_close(process_current, hid); + proc_handle_close(proc_cur, hid); SYSCALL_RETURN(0); } -handle_t _syscall_fs_wait(char __user *buf, long max_len, struct ufs_request __user *res) { - struct vfs_backend *backend = process_current->controlled; +hid_t _sys_fs_wait(char __user *buf, long max_len, struct ufs_request __user *res) { + VfsBackend *backend = proc_cur->controlled; // TODO can be used to tell if you're init if (!backend) SYSCALL_RETURN(-1); if (backend->usehcnt == 0) { @@ -279,22 +279,22 @@ handle_t _syscall_fs_wait(char __user *buf, long max_len, struct ufs_request __u SYSCALL_RETURN(-EPIPE); } - process_transition(process_current, PS_WAITS4REQUEST); + proc_setstate(proc_cur, PS_WAITS4REQUEST); if (backend->user.handler) panic_unimplemented(); - backend->user.handler = process_current; - process_current->awaited_req.buf = buf; - process_current->awaited_req.max_len = max_len; - process_current->awaited_req.res = res; + backend->user.handler = proc_cur; + proc_cur->awaited_req.buf = buf; + proc_cur->awaited_req.max_len = max_len; + proc_cur->awaited_req.res = res; vfs_backend_tryaccept(backend); // sets return value return -1; // dummy } -long _syscall_fs_respond(handle_t hid, const void __user *buf, long ret, int flags) { - struct handle *h = process_handle_get(process_current, hid); +long _sys_fs_respond(hid_t hid, const void __user *buf, long ret, int flags) { + Handle *h = proc_handle_get(proc_cur, hid); if (!h || h->type != HANDLE_FS_REQ) SYSCALL_RETURN(-EBADF); - struct vfs_request *req = h->req; + VfsReq *req = h->req; if (req) { if (req->output.len > 0 && ret > 0) { // if this vfsop outputs data and ret is positive, it's the length of the buffer @@ -303,19 +303,19 @@ long _syscall_fs_respond(handle_t hid, const void __user *buf, long ret, int fla ret = min(ret, capped_cast32(req->output.len)); ret = pcpy_bi( req->caller, req->output.buf, - process_current, buf, + proc_cur, buf, ret ); } - vfsreq_finish(req, (void __user *)buf, ret, flags, process_current); + vfsreq_finish(req, (void __user *)buf, ret, flags, proc_cur); } h->req = NULL; - process_handle_close(process_current, hid); + proc_handle_close(proc_cur, hid); SYSCALL_RETURN(0); } -void __user *_syscall_memflag(void __user *addr, size_t len, int flags) { - struct pagedir *pages = process_current->pages; +void __user *_sys_memflag(void __user *addr, size_t len, int flags) { + Pagedir *pages = proc_cur->pages; void *phys; addr = (userptr_t)((uintptr_t __force)addr & ~PAGE_MASK); // align to page boundary @@ -348,16 +348,16 @@ void __user *_syscall_memflag(void __user *addr, size_t len, int flags) { SYSCALL_RETURN((uintptr_t)addr); } -long _syscall_pipe(handle_t __user user_ends[2], int flags) { +long _sys_pipe(hid_t __user user_ends[2], int flags) { if (flags) SYSCALL_RETURN(-ENOSYS); - handle_t ends[2]; - struct handle *rend, *wend; - ends[0] = process_handle_init(process_current, HANDLE_PIPE, &rend); - ends[1] = process_handle_init(process_current, HANDLE_PIPE, &wend); + hid_t ends[2]; + Handle *rend, *wend; + ends[0] = proc_handle_init(proc_cur, HANDLE_PIPE, &rend); + ends[1] = proc_handle_init(proc_cur, HANDLE_PIPE, &wend); if (ends[0] < 0 || ends[1] < 0) { - process_handle_close(process_current, ends[0]); - process_handle_close(process_current, ends[1]); + proc_handle_close(proc_cur, ends[0]); + proc_handle_close(proc_cur, ends[1]); SYSCALL_RETURN(-EMFILE); } wend->pipe.sister = rend; @@ -365,55 +365,55 @@ long _syscall_pipe(handle_t __user user_ends[2], int flags) { wend->writeable = true; rend->readable = true; - pcpy_to(process_current, user_ends, ends, sizeof ends); + pcpy_to(proc_cur, user_ends, ends, sizeof ends); SYSCALL_RETURN(0); } -void _syscall_sleep(long ms) { +void _sys_sleep(long ms) { // TODO no overflow check - can leak current uptime - timer_schedule(process_current, uptime_ms() + ms); + timer_schedule(proc_cur, uptime_ms() + ms); } -void _syscall_filicide(void) { - process_filicide(process_current, -1); +void _sys_filicide(void) { + proc_filicide(proc_cur, -1); } -void _syscall_intr(void) { - for (struct process *p = process_current->child; p; p = process_next(p, process_current)) { - process_intr(p); +void _sys_intr(void) { + for (Proc *p = proc_cur->child; p; p = proc_next(p, proc_cur)) { + proc_intr(p); } } -void _syscall_intr_set(void __user *ip) { - process_current->intr_fn = ip; +void _sys_intr_set(void __user *ip) { + proc_cur->intr_fn = ip; } -long _syscall_execbuf(void __user *ubuf, size_t len) { +long _sys_execbuf(void __user *ubuf, size_t len) { if (len == 0) SYSCALL_RETURN(0); if (len > EXECBUF_MAX_LEN) SYSCALL_RETURN(-1); - if (process_current->execbuf.buf) + if (proc_cur->execbuf.buf) SYSCALL_RETURN(-1); // TODO consider supporting nesting execbufs char *kbuf = kmalloc(len); - if (pcpy_from(process_current, kbuf, ubuf, len) < len) { + if (pcpy_from(proc_cur, kbuf, ubuf, len) < len) { kfree(kbuf); SYSCALL_RETURN(-1); } - process_current->execbuf.buf = kbuf; - process_current->execbuf.len = len; - process_current->execbuf.pos = 0; + proc_cur->execbuf.buf = kbuf; + proc_cur->execbuf.len = len; + proc_cur->execbuf.pos = 0; SYSCALL_RETURN(0); } -void _syscall_debug_klog(const void __user *buf, size_t len) { +void _sys_debug_klog(const void __user *buf, size_t len) { if (false) { static char kbuf[256]; if (len >= sizeof(kbuf)) len = sizeof(kbuf) - 1; - pcpy_from(process_current, kbuf, buf, len); + pcpy_from(proc_cur, kbuf, buf, len); kbuf[len] = '\0'; - kprintf("[klog] %x\t%s\n", process_current->globalid, kbuf); + kprintf("[klog] %x\t%s\n", proc_cur->globalid, kbuf); } } @@ -421,30 +421,30 @@ long _syscall(long num, long a, long b, long c, long d, long e) { /* note: this isn't the only place where syscalls get called from! * see execbuf */ switch (num) { - break; case _SYSCALL_EXIT: _syscall_exit(a); - break; case _SYSCALL_AWAIT: _syscall_await(); - break; case _SYSCALL_FORK: _syscall_fork(a, (userptr_t)b); - break; case _SYSCALL_OPEN: _syscall_open((userptr_t)a, b, c); - break; case _SYSCALL_MOUNT: _syscall_mount(a, (userptr_t)b, c); - break; case _SYSCALL_DUP: _syscall_dup(a, b, c); - break; case _SYSCALL_READ: _syscall_read(a, (userptr_t)b, c, d); - break; case _SYSCALL_WRITE: _syscall_write(a, (userptr_t)b, c, d, e); - break; case _SYSCALL_GETSIZE: _syscall_getsize(a); - break; case _SYSCALL_REMOVE: _syscall_remove(a); - break; case _SYSCALL_CLOSE: _syscall_close(a); - break; case _SYSCALL_FS_WAIT: _syscall_fs_wait((userptr_t)a, b, (userptr_t)c); - break; case _SYSCALL_FS_RESPOND: _syscall_fs_respond(a, (userptr_t)b, c, d); - break; case _SYSCALL_MEMFLAG: _syscall_memflag((userptr_t)a, b, c); - break; case _SYSCALL_PIPE: _syscall_pipe((userptr_t)a, b); - break; case _SYSCALL_SLEEP: _syscall_sleep(a); - break; case _SYSCALL_FILICIDE: _syscall_filicide(); - break; case _SYSCALL_INTR: _syscall_intr(); - break; case _SYSCALL_INTR_SET: _syscall_intr_set((userptr_t)a); - break; case _SYSCALL_EXECBUF: _syscall_execbuf((userptr_t)a, b); - break; case _SYSCALL_DEBUG_KLOG: _syscall_debug_klog((userptr_t)a, b); + break; case _SYS_EXIT: _sys_exit(a); + break; case _SYS_AWAIT: _sys_await(); + break; case _SYS_FORK: _sys_fork(a, (userptr_t)b); + break; case _SYS_OPEN: _sys_open((userptr_t)a, b, c); + break; case _SYS_MOUNT: _sys_mount(a, (userptr_t)b, c); + break; case _SYS_DUP: _sys_dup(a, b, c); + break; case _SYS_READ: _sys_read(a, (userptr_t)b, c, d); + break; case _SYS_WRITE: _sys_write(a, (userptr_t)b, c, d, e); + break; case _SYS_GETSIZE: _sys_getsize(a); + break; case _SYS_REMOVE: _sys_remove(a); + break; case _SYS_CLOSE: _sys_close(a); + break; case _SYS_FS_WAIT: _sys_fs_wait((userptr_t)a, b, (userptr_t)c); + break; case _SYS_FS_RESPOND: _sys_fs_respond(a, (userptr_t)b, c, d); + break; case _SYS_MEMFLAG: _sys_memflag((userptr_t)a, b, c); + break; case _SYS_PIPE: _sys_pipe((userptr_t)a, b); + break; case _SYS_SLEEP: _sys_sleep(a); + break; case _SYS_FILICIDE: _sys_filicide(); + break; case _SYS_INTR: _sys_intr(); + break; case _SYS_INTR_SET: _sys_intr_set((userptr_t)a); + break; case _SYS_EXECBUF: _sys_execbuf((userptr_t)a, b); + break; case _SYS_DEBUG_KLOG: _sys_debug_klog((userptr_t)a, b); break; default: - regs_savereturn(&process_current->regs, -1); + regs_savereturn(&proc_cur->regs, -1); break; } /* return value is unused. execution continues in sysenter_stage2 */ diff --git a/src/kernel/types.h b/src/kernel/types.h new file mode 100644 index 0000000..e186479 --- /dev/null +++ b/src/kernel/types.h @@ -0,0 +1,17 @@ +#pragma once +#include <camellia/types.h> + +#define FORWARD_STRUCT(name) struct name; typedef struct name name; + +FORWARD_STRUCT(CpuRegs) +FORWARD_STRUCT(Handle) +FORWARD_STRUCT(Pagedir) +FORWARD_STRUCT(Proc) +FORWARD_STRUCT(VfsBackend) +FORWARD_STRUCT(VfsMount) +FORWARD_STRUCT(VfsReq) + +/* arch-specific stuff */ +FORWARD_STRUCT(GfxInfo) + +#undef FORWARD_STRUCT diff --git a/src/kernel/vfs/mount.c b/src/kernel/vfs/mount.c index 2815bb9..2518989 100644 --- a/src/kernel/vfs/mount.c +++ b/src/kernel/vfs/mount.c @@ -3,22 +3,22 @@ #include <kernel/vfs/mount.h> #include <shared/mem.h> -static struct vfs_mount *mount_root = NULL; +static VfsMount *mount_root = NULL; -struct vfs_mount *vfs_mount_seed(void) { +VfsMount *vfs_mount_seed(void) { return mount_root; } -void vfs_root_register(const char *path, void (*accept)(struct vfs_request *)) { - struct vfs_backend *backend = kmalloc(sizeof *backend); - struct vfs_mount *mount = kmalloc(sizeof *mount); - *backend = (struct vfs_backend) { +void vfs_root_register(const char *path, void (*accept)(VfsReq *)) { + VfsBackend *backend = kmalloc(sizeof *backend); + VfsMount *mount = kmalloc(sizeof *mount); + *backend = (VfsBackend) { .is_user = false, .usehcnt = 1, .provhcnt = 1, .kern.accept = accept, }; - *mount = (struct vfs_mount){ + *mount = (VfsMount){ .prev = mount_root, .prefix = path, .prefix_len = strlen(path), @@ -29,8 +29,8 @@ void vfs_root_register(const char *path, void (*accept)(struct vfs_request *)) { } -struct vfs_mount *vfs_mount_resolve( - struct vfs_mount *top, const char *path, size_t path_len) +VfsMount *vfs_mount_resolve( + VfsMount *top, const char *path, size_t path_len) { for (; top; top = top->prev) { if (top->prefix_len > path_len) @@ -49,12 +49,12 @@ struct vfs_mount *vfs_mount_resolve( return top; } -void vfs_mount_remref(struct vfs_mount *mnt) { +void vfs_mount_remref(VfsMount *mnt) { assert(mnt); assert(mnt->refs > 0); if (--(mnt->refs) > 0) return; - struct vfs_mount *prev = mnt->prev; + VfsMount *prev = mnt->prev; if (mnt->backend) { vfs_backend_refdown(mnt->backend, true); } diff --git a/src/kernel/vfs/mount.h b/src/kernel/vfs/mount.h index 6efdaa7..2e10dec 100644 --- a/src/kernel/vfs/mount.h +++ b/src/kernel/vfs/mount.h @@ -1,24 +1,25 @@ #pragma once +#include <kernel/types.h> #include <kernel/vfs/request.h> #include <stddef.h> -struct vfs_mount { - struct vfs_mount *prev; +struct VfsMount { + VfsMount *prev; const char *prefix; size_t prefix_len; bool prefix_owned; - struct vfs_backend *backend; + VfsBackend *backend; size_t refs; /* counts all references, atm from: - * - struct vfs_mount - * - struct proc + * - VfsMount + * - Proc */ }; // prepares init's filesystem view -struct vfs_mount *vfs_mount_seed(void); -struct vfs_mount *vfs_mount_resolve( - struct vfs_mount *top, const char *path, size_t path_len); +VfsMount *vfs_mount_seed(void); +VfsMount *vfs_mount_resolve( + VfsMount *top, const char *path, size_t path_len); /** Decrements the reference count, potentially freeing the mount. */ -void vfs_mount_remref(struct vfs_mount *mnt); +void vfs_mount_remref(VfsMount *mnt); -void vfs_root_register(const char *path, void (*accept)(struct vfs_request *)); +void vfs_root_register(const char *path, void (*accept)(VfsReq *)); diff --git a/src/kernel/vfs/procfs.c b/src/kernel/vfs/procfs.c index 78dad0d..2a8dd93 100644 --- a/src/kernel/vfs/procfs.c +++ b/src/kernel/vfs/procfs.c @@ -18,14 +18,14 @@ struct phandle { enum phandle_type type; }; -static struct phandle *openpath(const char *path, size_t len, struct process *root); -static struct process *findgid(uint32_t gid, struct process *root); -static void procfs_accept(struct vfs_request *req); -static void procfs_cleanup(struct vfs_backend *be); +static struct phandle *openpath(const char *path, size_t len, Proc *root); +static Proc *findgid(uint32_t gid, Proc *root); +static void procfs_accept(VfsReq *req); +static void procfs_cleanup(VfsBackend *be); static int isdigit(int c); static struct phandle * -openpath(const char *path, size_t len, struct process *p) +openpath(const char *path, size_t len, Proc *p) { struct phandle *h; enum phandle_type type; @@ -71,21 +71,21 @@ openpath(const char *path, size_t len, struct process *p) return h; } -static struct process * -findgid(uint32_t gid, struct process *root) +static Proc * +findgid(uint32_t gid, Proc *root) { - for (struct process *p = root; p; p = process_next(p, root)) { + for (Proc *p = root; p; p = proc_next(p, root)) { if (p->globalid == gid) return p; } return NULL; } static void -procfs_accept(struct vfs_request *req) +procfs_accept(VfsReq *req) { - struct process *root = req->backend->kern.data; + Proc *root = req->backend->kern.data; struct phandle *h = (__force void*)req->id; - struct process *p; + Proc *p; char buf[512]; assert(root); if (req->type == VFSOP_OPEN) { @@ -110,7 +110,7 @@ procfs_accept(struct vfs_request *req) } pos += snprintf(buf + pos, 512 - pos, "intr")+1; pos += snprintf(buf + pos, 512 - pos, "mem")+1; - for (struct process *iter = p->child; iter; iter = iter->sibling) { + for (Proc *iter = p->child; iter; iter = iter->sibling) { assert(pos < 512); // processes could possibly be identified by unique identifiers instead // e.g. an encrypted gid, or just a randomly generated one @@ -135,7 +135,7 @@ procfs_accept(struct vfs_request *req) ); vfsreq_finish_short(req, res); } else if (req->type == VFSOP_WRITE && h->type == PhIntr) { - process_intr(p); + proc_intr(p); vfsreq_finish_short(req, req->input.len); } else if (req->type == VFSOP_CLOSE) { kfree(h); @@ -146,9 +146,9 @@ procfs_accept(struct vfs_request *req) } static void -procfs_cleanup(struct vfs_backend *be) +procfs_cleanup(VfsBackend *be) { - struct process *p = be->kern.data; + Proc *p = be->kern.data; assert(p); p->refcount--; } @@ -158,11 +158,11 @@ isdigit(int c) { return '0' <= c && c <= '9'; } -struct vfs_backend * -procfs_backend(struct process *proc) +VfsBackend * +procfs_backend(Proc *proc) { - struct vfs_backend *be = kzalloc(sizeof(struct vfs_backend)); - *be = (struct vfs_backend) { + VfsBackend *be = kzalloc(sizeof(VfsBackend)); + *be = (VfsBackend) { .is_user = false, .provhcnt = 1, .usehcnt = 1, diff --git a/src/kernel/vfs/procfs.h b/src/kernel/vfs/procfs.h index 5ee4e96..4fb8c84 100644 --- a/src/kernel/vfs/procfs.h +++ b/src/kernel/vfs/procfs.h @@ -1,4 +1,4 @@ #pragma once #include <kernel/vfs/request.h> -struct vfs_backend *procfs_backend(struct process *proc); +VfsBackend *procfs_backend(Proc *proc); diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c index c98913a..7e5877d 100644 --- a/src/kernel/vfs/request.c +++ b/src/kernel/vfs/request.c @@ -7,12 +7,12 @@ #include <kernel/vfs/request.h> #include <shared/mem.h> -static void vfs_backend_user_accept(struct vfs_request *req); +static void vfs_backend_user_accept(VfsReq *req); -void vfsreq_create(struct vfs_request req_) { - struct vfs_request *req; +void vfsreq_create(VfsReq req_) { + VfsReq *req; if (req_.caller) { - process_transition(req_.caller, PS_WAITS4FS); + proc_setstate(req_.caller, PS_WAITS4FS); if (!req_.caller->reqslot) req_.caller->reqslot = kmalloc(sizeof *req); req = req_.caller->reqslot; @@ -34,7 +34,7 @@ void vfsreq_create(struct vfs_request req_) { // TODO if i add a handle field to vfs_request, check ->readable ->writeable here if (req->backend && req->backend->provhcnt) { - struct vfs_request **iter = &req->backend->queue; + VfsReq **iter = &req->backend->queue; while (*iter != NULL) // find free spot in queue iter = &(*iter)->queue_next; *iter = req; @@ -44,11 +44,11 @@ void vfsreq_create(struct vfs_request req_) { } } -void vfsreq_finish(struct vfs_request *req, char __user *stored, long ret, - int flags, struct process *handler) +void vfsreq_finish(VfsReq *req, char __user *stored, long ret, + int flags, Proc *handler) { if (req->type == VFSOP_OPEN && ret >= 0) { - struct handle *h; + Handle *h; if (!(flags & FSR_DELEGATE)) { /* default behavior - create a new handle for the file, wrap the id */ h = handle_init(HANDLE_FILE); @@ -60,14 +60,14 @@ void vfsreq_finish(struct vfs_request *req, char __user *stored, long ret, } else { /* delegating - moving a handle to the caller */ assert(handler); - h = process_handle_take(handler, ret); + h = proc_hid_take(handler, ret); // TODO don't ignore OPEN_RO } if (h) { // TODO write tests for caller getting killed while opening a file if (!req->caller) panic_unimplemented(); - ret = process_handle_put(req->caller, h); + ret = proc_handle_put(req->caller, h); if (ret < 0) ret = -EMFILE; } else { ret = -1; @@ -83,14 +83,14 @@ void vfsreq_finish(struct vfs_request *req, char __user *stored, long ret, if (req->caller) { assert(req->caller->state == PS_WAITS4FS); regs_savereturn(&req->caller->regs, ret); - process_transition(req->caller, PS_RUNNING); + proc_setstate(req->caller, PS_RUNNING); } else { kfree(req); } } -void vfs_backend_tryaccept(struct vfs_backend *backend) { - struct vfs_request *req = backend->queue; +void vfs_backend_tryaccept(VfsBackend *backend) { + VfsReq *req = backend->queue; if (!req) return; if (backend->is_user && !backend->user.handler) return; @@ -103,8 +103,8 @@ void vfs_backend_tryaccept(struct vfs_backend *backend) { } } -static void vfs_backend_user_accept(struct vfs_request *req) { - struct process *handler; +static void vfs_backend_user_accept(VfsReq *req) { + Proc *handler; struct ufs_request res = {0}; int len; @@ -143,26 +143,26 @@ static void vfs_backend_user_accept(struct vfs_request *req) { panic_unimplemented(); } - struct handle *h; - handle_t hid = process_handle_init(handler, HANDLE_FS_REQ, &h); + Handle *h; + hid_t hid = proc_handle_init(handler, HANDLE_FS_REQ, &h); if (hid < 0) panic_unimplemented(); h->req = req; - process_transition(handler, PS_RUNNING); + proc_setstate(handler, PS_RUNNING); regs_savereturn(&handler->regs, hid); req->backend->user.handler = NULL; return; } -void vfs_backend_refdown(struct vfs_backend *b, bool use) { +void vfs_backend_refdown(VfsBackend *b, bool use) { size_t *field = use ? &b->usehcnt : &b->provhcnt; assert(b); assert(0 < *field); *field -= 1; if (b->provhcnt == 0 && use == false) { - struct vfs_request *q = b->queue; + VfsReq *q = b->queue; while (q) { - struct vfs_request *q2 = q->queue_next; + VfsReq *q2 = q->queue_next; vfsreq_finish_short(q, -1); q = q2; } @@ -173,11 +173,11 @@ void vfs_backend_refdown(struct vfs_backend *b, bool use) { b->kern.cleanup(b); } if (b->is_user && b->user.handler) { - struct process *p = b->user.handler; + Proc *p = b->user.handler; b->user.handler = NULL; assert(p->state == PS_WAITS4REQUEST); regs_savereturn(&p->regs, -EPIPE); - process_transition(p, PS_RUNNING); + proc_setstate(p, PS_RUNNING); } } if (b->usehcnt == 0 && b->provhcnt == 0) { diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h index 4d7fa01..182202c 100644 --- a/src/kernel/vfs/request.h +++ b/src/kernel/vfs/request.h @@ -1,38 +1,38 @@ #pragma once -#include <camellia/types.h> +#include <kernel/types.h> #include <stdbool.h> #include <stddef.h> -// describes something which can act as an access function -struct vfs_backend { +/* describes something which can act as an access function */ +struct VfsBackend { /* amount of using references - * struct vfs_mount - * struct vfs_request - * struct handle + * VfsMount + * VfsReq + * Handle * once it reaches 0, it'll never increase */ - size_t usehcnt; /* struct vfs_mount */ + size_t usehcnt; /* VfsMount */ /* amount of providing references - * struct process + * Proc * 0 - orphaned, will never increase */ size_t provhcnt; - struct vfs_request *queue; + VfsReq *queue; bool is_user; union { struct { - struct process *handler; + Proc *handler; } user; struct { - void (*accept)(struct vfs_request *); - void (*cleanup)(struct vfs_backend *); + void (*accept)(VfsReq *); + void (*cleanup)(VfsBackend *); void *data; } kern; }; }; -// describes an in-process vfs call -struct vfs_request { - enum vfs_operation type; +/* describes an in-progress vfs call */ +struct VfsReq { + enum vfs_op type; struct { bool kern; // if false: use .buf ; if true: use .buf_kern union { @@ -54,26 +54,26 @@ struct vfs_request { /* if caller != NULL, owned by it - don't free, the allocation will be reused * if caller == NULL, free on finish */ - struct process *caller; - struct vfs_backend *backend; + Proc *caller; + VfsBackend *backend; - struct vfs_request *queue_next; - struct vfs_request *postqueue_next; /* used by kernel backends */ + VfsReq *queue_next; + VfsReq *postqueue_next; /* used by kernel backends */ /* only one of these queues is in use at a given moment, they could * be merged into a single field */ }; /** Assigns the vfs_request to the caller, and dispatches the call */ -void vfsreq_create(struct vfs_request); -void vfsreq_finish(struct vfs_request*, char __user *stored, long ret, int flags, struct process *handler); +void vfsreq_create(VfsReq); +void vfsreq_finish(VfsReq*, char __user *stored, long ret, int flags, Proc *handler); -static inline void vfsreq_finish_short(struct vfs_request *req, long ret) { +static inline void vfsreq_finish_short(VfsReq *req, long ret) { vfsreq_finish(req, (void __user *)ret, ret, 0, NULL); } /** Try to accept an enqueued request */ -void vfs_backend_tryaccept(struct vfs_backend *); +void vfs_backend_tryaccept(VfsBackend *); // TODO the bool arg is confusing. maybe this should just be a function // that verified the refcount and potentially frees the backend -void vfs_backend_refdown(struct vfs_backend *, bool use); +void vfs_backend_refdown(VfsBackend *, bool use); |