WIP 2
This commit is contained in:
@ -55,7 +55,6 @@ SRCFILES += $(call GRABSRC, \
|
||||
proc \
|
||||
proc/kproc \
|
||||
proc/ps2kbproc \
|
||||
proc/termproc \
|
||||
proc/serialproc \
|
||||
hal \
|
||||
hal/$(ARCH) \
|
||||
@ -67,6 +66,7 @@ SRCFILES += $(call GRABSRC, \
|
||||
rbuf \
|
||||
ipc/pipe \
|
||||
drivers/ps2kb \
|
||||
dev \
|
||||
)
|
||||
|
||||
ifeq ($(ARCH),x86_64)
|
||||
|
@ -11,7 +11,7 @@ CFLAGS += -m64 \
|
||||
-mno-red-zone \
|
||||
-fno-stack-protector \
|
||||
-fno-stack-check \
|
||||
-O0 \
|
||||
-Os \
|
||||
|
||||
LDFLAGS += -m elf_x86_64 \
|
||||
-pie \
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <stdbool.h>
|
||||
#include "bitmap.h"
|
||||
#include "util/util.h"
|
||||
#include "kprintf.h"
|
||||
|
||||
void *bitmap_toptr(BitMap *bm, size_t block) {
|
||||
uint8_t *ptr = (uint8_t *)(bm->mem_start + (block * BITMAP_BLOCK_SIZE));
|
||||
@ -104,13 +105,3 @@ void *bitmap_alloc(BitMap *bm, size_t blocks) {
|
||||
void bitmap_free(BitMap *bm, void *base, size_t blocks) {
|
||||
bitmap_markregion(bm, base, BITMAP_BLOCK_SIZE * blocks, 0);
|
||||
}
|
||||
|
||||
size_t bitmap_allocpageframe(BitMap *bm) {
|
||||
size_t pickedreg = bitmap_freeregion(bm, 1);
|
||||
bitmap_markblocks(bm, pickedreg, 1, 1);
|
||||
return (bm->mem_start + (pickedreg * BITMAP_BLOCK_SIZE));
|
||||
}
|
||||
|
||||
void bitmap_freepageframe(BitMap *bm, void *addr) {
|
||||
bitmap_markregion(bm, addr, BITMAP_BLOCK_SIZE * 1, 0);
|
||||
}
|
||||
|
@ -31,7 +31,5 @@ void bitmap_markregion(BitMap *bm, void *baseptr, size_t size, bool is_used);
|
||||
size_t bitmap_freeregion(BitMap *bm, size_t blocks);
|
||||
void *bitmap_alloc(BitMap *bm, size_t blocks);
|
||||
void bitmap_free(BitMap *bm, void *base, size_t blocks);
|
||||
size_t bitmap_allocpageframe(BitMap *bm);
|
||||
void bitmap_freepageframe(BitMap *bm, void *addr);
|
||||
|
||||
#endif // BITMAP_BITMAP_H_
|
||||
|
14
kernel/dev/dev.h
Normal file
14
kernel/dev/dev.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef DEV_DEV_H_
|
||||
#define DEV_DEV_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define DEV_FNS_MAX 32
|
||||
|
||||
typedef int32_t (*DevFn)(uint8_t *buffer, size_t len, void *extra);
|
||||
|
||||
typedef struct {
|
||||
DevFn fns[DEV_FNS_MAX];
|
||||
} Dev;
|
||||
|
||||
#endif // DEV_DEV_H_
|
19
kernel/dev/termdev.c
Normal file
19
kernel/dev/termdev.c
Normal file
@ -0,0 +1,19 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "kprintf.h"
|
||||
#include "hal/hal.h"
|
||||
#include "termdev.h"
|
||||
#include "dev.h"
|
||||
#include "errors.h"
|
||||
|
||||
Dev TERMDEV;
|
||||
|
||||
int32_t termdev_putch(uint8_t *buffer, size_t len, void *extra) {
|
||||
kprintf("%.*s", (int)len, (char *)buffer);
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
void termdev_init(void) {
|
||||
hal_memset(&TERMDEV, 0, sizeof(TERMDEV));
|
||||
TERMDEV.fns[0] = &termdev_putch;
|
||||
}
|
13
kernel/dev/termdev.h
Normal file
13
kernel/dev/termdev.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef DEV_TERMDEV_H_
|
||||
#define DEV_TERMDEV_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "dev.h"
|
||||
|
||||
int32_t termdev_putch(uint8_t *buffer, size_t len, void *extra);
|
||||
void termdev_init(void);
|
||||
|
||||
extern Dev TERMDEV;
|
||||
|
||||
#endif // DEV_TERMDEV_H_
|
@ -49,7 +49,7 @@ int RELEASE_LOCK(SpinLock *sl) {
|
||||
}
|
||||
|
||||
int INITIAL_LOCK(SpinLock *sl) {
|
||||
spinlock_release(sl);
|
||||
spinlock_init(sl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
#define GDT_PRESENT 0x80
|
||||
#define GDT_TSS 0x89
|
||||
|
||||
#define KSTACK 8192
|
||||
#define KSTACK (1024*2*4096)
|
||||
ALIGNED(16) static uint8_t kernelstack[KSTACK];
|
||||
|
||||
typedef struct {
|
||||
|
@ -178,8 +178,6 @@ void hal_syscalldispatch(IntrStackFrame *frame) {
|
||||
frame->regs.rax = E_BADSYSCALL;
|
||||
return;
|
||||
}
|
||||
uint64_t cr3;
|
||||
asm volatile("mov %%cr3, %0" : "=r"(cr3));
|
||||
int32_t ret = fn(frame, frame->regs.rdi, frame->regs.rsi, frame->regs.rdx,
|
||||
frame->regs.r10, frame->regs.r8, frame->regs.r9);
|
||||
|
||||
@ -215,7 +213,7 @@ void intr_handleintr(IntrStackFrame *frame) {
|
||||
break;
|
||||
case INTR_IRQBASE+1:
|
||||
int32_t c = ps2kb_intr();
|
||||
if (c >= 0) {
|
||||
if (c >= 0 && PS2KB_BUF.init) {
|
||||
uint8_t b = c;
|
||||
spinlock_acquire(&PS2KB_BUF.spinlock);
|
||||
rbuf_push(&PS2KB_BUF.rbuf, b);
|
||||
|
@ -62,13 +62,13 @@
|
||||
.endm
|
||||
|
||||
.macro _vecintr_bodygen
|
||||
cli
|
||||
_push_regs
|
||||
cld
|
||||
mov %rsp, %rdi
|
||||
movq %rsp, %rdi
|
||||
call intr_handleintr
|
||||
_pop_regs
|
||||
add $0x10, %rsp
|
||||
|
||||
iretq
|
||||
.endm
|
||||
|
||||
|
@ -2,15 +2,11 @@
|
||||
|
||||
.global hal_switchproc
|
||||
hal_switchproc:
|
||||
mov %cr3, %rcx
|
||||
cmp %rsi, %rcx
|
||||
je .done
|
||||
mov %rsi, %cr3
|
||||
.done:
|
||||
testq %rsi, %rsi
|
||||
je 1f
|
||||
movq %rsi, %cr3
|
||||
1:
|
||||
mov %rdi, %rsp
|
||||
|
||||
_pop_regs
|
||||
add $0x10, %rsp
|
||||
|
||||
iretq
|
||||
|
||||
|
@ -29,12 +29,16 @@ PgIndex hal_vmm_pageindex(uint64_t vaddr) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t *hal_vmm_nexttable(uint64_t *table, uint64_t ent) {
|
||||
uint64_t *hal_vmm_nexttable(uint64_t *table, uint64_t ent, bool alloc) {
|
||||
uint64_t entry = table[ent];
|
||||
uint64_t phys;
|
||||
if (entry & HAL_PG_PRESENT) {
|
||||
phys = entry & ~0xFFFULL;
|
||||
} else {
|
||||
if (!alloc) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t *newphys = pmm_alloc(1);
|
||||
phys = (uint64_t)newphys;
|
||||
hal_memset(VIRT(phys), 0, HAL_PAGE_SIZE);
|
||||
@ -47,9 +51,9 @@ void hal_vmm_map_page(uint64_t cr3phys, uint64_t virtaddr, uint64_t physaddr, ui
|
||||
uint64_t *pml4 = (uint64_t *)VIRT(cr3phys);
|
||||
PgIndex pi = hal_vmm_pageindex(virtaddr);
|
||||
|
||||
uint64_t *pml3 = hal_vmm_nexttable(pml4, pi.pml4);
|
||||
uint64_t *pml2 = hal_vmm_nexttable(pml3, pi.pml3);
|
||||
uint64_t *pml1 = hal_vmm_nexttable(pml2, pi.pml2);
|
||||
uint64_t *pml3 = hal_vmm_nexttable(pml4, pi.pml4, true);
|
||||
uint64_t *pml2 = hal_vmm_nexttable(pml3, pi.pml3, true);
|
||||
uint64_t *pml1 = hal_vmm_nexttable(pml2, pi.pml2, true);
|
||||
uint64_t *pte = &pml1[pi.pml1];
|
||||
|
||||
*pte = (physaddr & ~0xFFFULL) | ((uint64_t)flags & 0x7ULL);
|
||||
@ -59,9 +63,9 @@ void hal_vmm_unmap_page(uint64_t cr3phys, uint64_t virtaddr, uint64_t physaddr)
|
||||
uint64_t *pml4 = (uint64_t *)VIRT(cr3phys);
|
||||
PgIndex pi = hal_vmm_pageindex(virtaddr);
|
||||
|
||||
uint64_t *pml3 = hal_vmm_nexttable(pml4, pi.pml4);
|
||||
uint64_t *pml2 = hal_vmm_nexttable(pml3, pi.pml3);
|
||||
uint64_t *pml1 = hal_vmm_nexttable(pml2, pi.pml2);
|
||||
uint64_t *pml3 = hal_vmm_nexttable(pml4, pi.pml4, false);
|
||||
uint64_t *pml2 = hal_vmm_nexttable(pml3, pi.pml3, false);
|
||||
uint64_t *pml1 = hal_vmm_nexttable(pml2, pi.pml2, false);
|
||||
uint64_t *pte = &pml1[pi.pml1];
|
||||
|
||||
*pte &= ~HAL_PG_PRESENT;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "storedev/storedev.h"
|
||||
#include "util/util.h"
|
||||
#include "proc/proc.h"
|
||||
#include "dev/termdev.h"
|
||||
|
||||
const char *human_size(uint64_t bytes, char *buf, size_t bufsize) {
|
||||
static const char *units[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB" };
|
||||
@ -64,6 +65,7 @@ void kmain(void) {
|
||||
storedev_init();
|
||||
baseimg_init();
|
||||
vfs_init();
|
||||
termdev_init();
|
||||
proc_init();
|
||||
|
||||
for(;;);
|
||||
|
@ -40,6 +40,9 @@ void pmm_init(void) {
|
||||
hal_memset(bm->map, 0xff, bm->nbytes);
|
||||
for (size_t i = 0; i < BOOT_INFO.memmap_entrycount; i++) {
|
||||
struct limine_memmap_entry *entry = BOOT_INFO.memmap_entries[i];
|
||||
if (entry == memmap_ent) {
|
||||
continue;
|
||||
}
|
||||
// mark usable as 0 and unusable as 1
|
||||
bitmap_markregion(bm, (void *)entry->base, entry->length, entry->type != LIMINE_MEMMAP_USABLE);
|
||||
}
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "ipc/pipe/pipe.h"
|
||||
#include "kproc/kproc.h"
|
||||
#include "ps2kbproc/ps2kbproc.h"
|
||||
#include "termproc/termproc.h"
|
||||
#include "serialproc/serialproc.h"
|
||||
#include "sysdefs/processctl.h"
|
||||
|
||||
@ -181,6 +180,7 @@ Proc *proc_spawnuser(char *mountpoint, char *path) {
|
||||
proc->mman_map_base = PROC_MMAN_MAP_BASE;
|
||||
spinlock_init(&proc->bcast_pipes.spinlock);
|
||||
spinlock_init(&proc->pipes_spinlock);
|
||||
spinlock_init(&proc->devs_spinlock);
|
||||
|
||||
proc->pipes[0] = dlmalloc(sizeof(IpcPipe));
|
||||
ipc_pipeinit(proc->pipes[0], proc->pid);
|
||||
@ -308,26 +308,20 @@ void proc_init(void) {
|
||||
spinlock_init(&PROCS.spinlock);
|
||||
PROCS.procs = NULL;
|
||||
|
||||
kproc_init(proc_spawnkern(&kproc_fn, "kproc"));
|
||||
proc_register(KPROC);
|
||||
PROCS.current = KPROC;
|
||||
KPROC->state = PROC_READY;
|
||||
/* kproc_init(proc_spawnkern(&kproc_fn, "kproc")); */
|
||||
/* proc_register(KPROC); */
|
||||
/* PROCS.current = KPROC; */
|
||||
/* KPROC->state = PROC_READY; */
|
||||
|
||||
ps2kbproc_init(proc_spawnkern(&ps2kbproc_fn, "ps2kbproc"));
|
||||
proc_register(PS2KBPROC);
|
||||
PS2KBPROC->state = PROC_READY;
|
||||
|
||||
termproc_init(proc_spawnkern(&termproc_fn, "termproc"));
|
||||
proc_register(TERMPROC);
|
||||
TERMPROC->state = PROC_READY;
|
||||
/* ps2kbproc_init(proc_spawnkern(&ps2kbproc_fn, "ps2kbproc")); */
|
||||
/* proc_register(PS2KBPROC); */
|
||||
/* PS2KBPROC->state = PROC_READY; */
|
||||
|
||||
/* serialproc_init(proc_spawnkern(&serialproc_fn, "serialproc")); */
|
||||
/* proc_register(SERIALPROC); */
|
||||
|
||||
Proc *init = proc_spawnuser("base", "/bin/init");
|
||||
ipc_pipefree(init->pipes[0]);
|
||||
dlfree(init->pipes[0]);
|
||||
init->pipes[0] = TERMPROC->pipes[1];
|
||||
PROCS.current = init;
|
||||
proc_register(init);
|
||||
init->state = PROC_READY;
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "vfs/vfs.h"
|
||||
#include "ipc/pipe/pipe.h"
|
||||
#include "sysdefs/processctl.h"
|
||||
#include "dev/dev.h"
|
||||
|
||||
#define PROC_NAME_MAX 0x100
|
||||
|
||||
@ -18,9 +19,10 @@
|
||||
|
||||
#define PROC_VFSHANDLES_MAX 0x80
|
||||
#define PROC_PIPEHANDLES_MAX 0x20
|
||||
#define PROC_DEVHANDLES_MAX 0x20
|
||||
|
||||
#define PROC_MMAN_MAP_BASE 0x0000100000000000ULL
|
||||
#define PROC_USER_STACK_TOP 0x0000800000000000ULL
|
||||
#define PROC_USER_STACK_TOP 0x00007FFFFFFFF000ULL
|
||||
|
||||
typedef struct {
|
||||
IntrStackFrame trapframe;
|
||||
@ -56,12 +58,18 @@ typedef struct Proc {
|
||||
|
||||
VfsObj *vobjs[PROC_VFSHANDLES_MAX];
|
||||
uint64_t vobjcnt;
|
||||
|
||||
IpcPipe *pipes[PROC_PIPEHANDLES_MAX];
|
||||
SpinLock pipes_spinlock;
|
||||
|
||||
struct {
|
||||
IpcPipe *list;
|
||||
SpinLock spinlock;
|
||||
} bcast_pipes;
|
||||
|
||||
Dev *devs[PROC_DEVHANDLES_MAX];
|
||||
SpinLock devs_spinlock;
|
||||
|
||||
struct {
|
||||
ProcArg *list;
|
||||
size_t len;
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "ps2kbproc.h"
|
||||
|
||||
Proc *PS2KBPROC = NULL;
|
||||
Ps2KbFastBuf PS2KB_BUF;
|
||||
Ps2KbFastBuf PS2KB_BUF = {0};
|
||||
|
||||
void ps2kbproc_init(Proc *proc) {
|
||||
PS2KBPROC = proc;
|
||||
@ -17,22 +17,23 @@ void ps2kbproc_init(Proc *proc) {
|
||||
uint8_t *buf = dlmalloc(IPC_PIPE_MAX);
|
||||
rbuf_init(&PS2KB_BUF.rbuf, buf, IPC_PIPE_MAX);
|
||||
spinlock_init(&PS2KB_BUF.spinlock);
|
||||
PS2KB_BUF.init = true;
|
||||
}
|
||||
|
||||
void ps2kbproc_fn(void) {
|
||||
for (;;) {
|
||||
uint8_t b = 0;
|
||||
spinlock_acquire(&PS2KB_BUF.spinlock);
|
||||
if (rbuf_pop(&PS2KB_BUF.rbuf, &b) == 0) {
|
||||
spinlock_acquire(&PS2KBPROC->bcast_pipes.spinlock);
|
||||
IpcPipe *head = PS2KBPROC->bcast_pipes.list;
|
||||
while (head != NULL) {
|
||||
ipc_pipewrite(head, &b, 1);
|
||||
head = head->next;
|
||||
}
|
||||
spinlock_release(&PS2KBPROC->bcast_pipes.spinlock);
|
||||
}
|
||||
spinlock_release(&PS2KB_BUF.spinlock);
|
||||
/* uint8_t b = 0; */
|
||||
/* spinlock_acquire(&PS2KB_BUF.spinlock); */
|
||||
/* if (rbuf_pop(&PS2KB_BUF.rbuf, &b) == 0) { */
|
||||
/* spinlock_acquire(&PS2KBPROC->bcast_pipes.spinlock); */
|
||||
/* IpcPipe *head = PS2KBPROC->bcast_pipes.list; */
|
||||
/* while (head != NULL) { */
|
||||
/* ipc_pipewrite(head, &b, 1); */
|
||||
/* head = head->next; */
|
||||
/* } */
|
||||
/* spinlock_release(&PS2KBPROC->bcast_pipes.spinlock); */
|
||||
/* } */
|
||||
/* spinlock_release(&PS2KB_BUF.spinlock); */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
typedef struct {
|
||||
RBuf rbuf;
|
||||
SpinLock spinlock;
|
||||
bool init;
|
||||
} Ps2KbFastBuf;
|
||||
|
||||
extern Proc *PS2KBPROC;
|
||||
|
@ -1,25 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include "proc/proc.h"
|
||||
#include "ipc/pipe/pipe.h"
|
||||
#include "kprintf.h"
|
||||
#include "hal/hal.h"
|
||||
#include "dlmalloc/malloc.h"
|
||||
#include "spinlock/spinlock.h"
|
||||
|
||||
Proc *TERMPROC;
|
||||
|
||||
void termproc_init(Proc *proc) {
|
||||
TERMPROC = proc;
|
||||
TERMPROC->pipes[1] = dlmalloc(sizeof(IpcPipe));
|
||||
ipc_pipeinit(TERMPROC->pipes[1], TERMPROC->pid);
|
||||
}
|
||||
|
||||
void termproc_fn(void) {
|
||||
for (;;) {
|
||||
char c = 0;
|
||||
int32_t read = ipc_piperead(TERMPROC->pipes[1], (uint8_t *)&c, 1);
|
||||
if (read > 0) {
|
||||
kprintf("%c", c);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#ifndef PROC_TERMPROC_TERMPROC_H_
|
||||
#define PROC_TERMPROC_TERMPROC_H_
|
||||
|
||||
#include "proc/proc.h"
|
||||
|
||||
extern Proc *TERMPROC;
|
||||
|
||||
void termproc_init(Proc *proc);
|
||||
void termproc_fn(void);
|
||||
|
||||
#endif // PROC_TERMPROC_TERMPROC_H_
|
@ -5,25 +5,62 @@
|
||||
#include "hal/hal.h"
|
||||
#include "kprintf.h"
|
||||
|
||||
#define SPINLOCK_IRQ_DBG 1
|
||||
|
||||
#define SPINLOCK_HINT() asm volatile("pause")
|
||||
|
||||
struct {
|
||||
atomic_uint64_t irq_flags;
|
||||
atomic_int irq_nest;
|
||||
} IRQ_CTX;
|
||||
|
||||
void spinlock_init(SpinLock *sl) {
|
||||
atomic_store(&sl->lock, false);
|
||||
sl->flags = 0;
|
||||
}
|
||||
|
||||
uint64_t spinlock_irqsave(void) {
|
||||
uint64_t irqsave(void) {
|
||||
uint64_t flags;
|
||||
asm volatile("pushfq; cli; popq %0" : "=r"(flags) :: "memory");
|
||||
asm volatile("pushfq; cli; popq %0" : "=r"(flags) :: "memory", "cc");
|
||||
return flags;
|
||||
}
|
||||
|
||||
void spinlock_irqrestore(uint64_t flags) {
|
||||
void irqrestore(uint64_t flags) {
|
||||
if (flags & (1<<9)) {
|
||||
asm volatile("sti" ::: "memory");
|
||||
asm volatile("sti" ::: "memory", "cc");
|
||||
}
|
||||
}
|
||||
|
||||
void irqsave_nested(void) {
|
||||
if (atomic_load(&IRQ_CTX.irq_nest) == 0) {
|
||||
atomic_store(&IRQ_CTX.irq_flags, irqsave());
|
||||
}
|
||||
atomic_inc(&IRQ_CTX.irq_nest);
|
||||
|
||||
#if SPINLOCK_IRQ_DBG
|
||||
if (atomic_load(&IRQ_CTX.irq_nest) < 0) {
|
||||
kprintf("IRQ_CTX.irq_nest underflow\n");
|
||||
hal_hang();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void irqrestore_nested(void) {
|
||||
#if SPINLOCK_IRQ_DBG
|
||||
int irq_nest = atomic_load(&IRQ_CTX.irq_nest);
|
||||
if (irq_nest <= 0) {
|
||||
kprintf("spinlock: irqs restored too many times: %d\n", irq_nest);
|
||||
hal_hang();
|
||||
}
|
||||
#endif
|
||||
|
||||
atomic_dec(&IRQ_CTX.irq_nest);
|
||||
if (atomic_load(&IRQ_CTX.irq_nest) == 0) {
|
||||
irqrestore(atomic_load(&IRQ_CTX.irq_flags));
|
||||
}
|
||||
}
|
||||
|
||||
void spinlock_acquire(SpinLock *sl) {
|
||||
sl->flags = spinlock_irqsave();
|
||||
irqsave_nested();
|
||||
|
||||
while (atomic_test_and_set_explicit(&sl->lock, memory_order_acquire)) {
|
||||
SPINLOCK_HINT();
|
||||
@ -33,6 +70,6 @@ void spinlock_acquire(SpinLock *sl) {
|
||||
void spinlock_release(SpinLock *sl) {
|
||||
atomic_clear_flag_explicit(&sl->lock, memory_order_release);
|
||||
|
||||
spinlock_irqrestore(sl->flags);
|
||||
irqrestore_nested();
|
||||
}
|
||||
|
||||
|
@ -6,11 +6,8 @@
|
||||
|
||||
typedef struct {
|
||||
atomic_bool lock;
|
||||
uint64_t flags;
|
||||
} SpinLock;
|
||||
|
||||
#define SPINLOCK_HINT() asm volatile("pause")
|
||||
|
||||
void spinlock_init(SpinLock *sl);
|
||||
void spinlock_acquire(SpinLock *sl);
|
||||
void spinlock_release(SpinLock *sl);
|
||||
|
65
kernel/syscall/devctl.c
Normal file
65
kernel/syscall/devctl.c
Normal file
@ -0,0 +1,65 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "kprintf.h"
|
||||
#include "syscall.h"
|
||||
#include "errors.h"
|
||||
#include "spinlock/spinlock.h"
|
||||
#include "proc/proc.h"
|
||||
#include "sysdefs/devctl.h"
|
||||
#include "dev/termdev.h"
|
||||
#include "util/util.h"
|
||||
|
||||
Dev *DEVS[] = {
|
||||
[0x10] = &TERMDEV,
|
||||
};
|
||||
|
||||
int32_t SYSCALL5(sys_devctl, devh1, cmd1, buffer1, len1, extra1) {
|
||||
uint64_t *devh = (uint64_t *)devh1;
|
||||
uint64_t cmd = cmd1;
|
||||
int32_t ret = E_OK;
|
||||
|
||||
spinlock_acquire(&PROCS.spinlock);
|
||||
Proc *proc = PROCS.current;
|
||||
spinlock_release(&PROCS.spinlock);
|
||||
|
||||
switch (cmd) {
|
||||
case DEVCTL_GET_HANDLE: {
|
||||
uint64_t devid = buffer1;
|
||||
if (devid >= LEN(DEVS)) {
|
||||
ret = E_INVALIDARGUMENT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
for (size_t i = 0; i < PROC_DEVHANDLES_MAX; i++) {
|
||||
if (proc->devs[i] == NULL) {
|
||||
found = true;
|
||||
proc->devs[i] = DEVS[devid];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
ret = E_NOENTRY;
|
||||
goto done;
|
||||
}
|
||||
} break;
|
||||
default: {
|
||||
if (devh == NULL) {
|
||||
ret = E_INVALIDARGUMENT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (cmd >= DEV_FNS_MAX) {
|
||||
ret = E_INVALIDARGUMENT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
Dev *dev = proc->devs[*devh];
|
||||
ret = dev->fns[cmd]((uint8_t *)buffer1, (size_t)len1, (void *)extra1);
|
||||
} break;
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
9
kernel/syscall/devctl.h
Normal file
9
kernel/syscall/devctl.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef SYSCALL_DEVCTL_H_
|
||||
#define SYSCALL_DEVCTL_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "syscall.h"
|
||||
|
||||
int32_t SYSCALL5(sys_devctl, devh1, cmd1, buffer1, len1, extra1);
|
||||
|
||||
#endif // SYSCALL_DEVCTL_H_
|
@ -10,6 +10,7 @@
|
||||
#include "sysdefs/mman.h"
|
||||
#include "bootinfo/bootinfo.h"
|
||||
#include "dlmalloc/malloc.h"
|
||||
#include "kprintf.h"
|
||||
|
||||
int32_t SYSCALL5(sys_mman_map, addr1, size1, prot1, flags1, out1) {
|
||||
uint8_t *addr = (uint8_t *)addr1;
|
||||
@ -27,9 +28,6 @@ int32_t SYSCALL5(sys_mman_map, addr1, size1, prot1, flags1, out1) {
|
||||
|
||||
size_t pages = _DIV_ROUNDUP(size, HAL_PAGE_SIZE);
|
||||
uint8_t *phys = (uint8_t *)pmm_alloc(pages);
|
||||
if (phys == NULL) {
|
||||
return E_NOMEMORY;
|
||||
}
|
||||
hal_memset(VIRT(phys), 0, pages * HAL_PAGE_SIZE);
|
||||
|
||||
spinlock_acquire(&PROCS.spinlock);
|
||||
|
@ -63,8 +63,10 @@ int32_t SYSCALL5(sys_processctl, pid1, cmd1, arg1, arg2, arg3) {
|
||||
|
||||
size_t argslen = arg3;
|
||||
char *(*args)[] = (char *(*)[])arg2;
|
||||
for (size_t i = 0; i < argslen; i++) {
|
||||
PROC_ARG(newproc, (*args)[i]);
|
||||
if (args != NULL && argslen > 0) {
|
||||
for (size_t i = 0; i < argslen; i++) {
|
||||
PROC_ARG(newproc, (*args)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < PROC_PIPEHANDLES_MAX; i++) {
|
||||
|
@ -11,7 +11,7 @@ int32_t SYSCALL0(sys_schedrelease) {
|
||||
Proc *proc = PROCS.current;
|
||||
spinlock_release(&PROCS.spinlock);
|
||||
|
||||
proc_sched((void *)frame);
|
||||
/* proc_sched((void *)frame); */
|
||||
|
||||
return E_OK;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "ipcpipe.h"
|
||||
#include "mman.h"
|
||||
#include "sched.h"
|
||||
#include "devctl.h"
|
||||
|
||||
int32_t SYSCALL1(sys_debugprint, string) {
|
||||
char *p = (char *)string;
|
||||
@ -23,4 +24,5 @@ SyscallFn SYSCALL_TABLE[SYSCALLS_MAX] = {
|
||||
[SYS_MMAN_MAP] = &sys_mman_map,
|
||||
[SYS_MMAN_UNMAP] = &sys_mman_unmap,
|
||||
[SYS_SCHEDRELEASE] = &sys_schedrelease,
|
||||
[SYS_DEVCTL] = &sys_devctl,
|
||||
};
|
||||
|
@ -58,14 +58,14 @@
|
||||
} while(0)
|
||||
|
||||
#define LL_FOREACH_SAFE(head, var, tmp) \
|
||||
for (typeof(head) var = (head), tmp = (var ? var->next : NULL); \
|
||||
for (var = (head), tmp = (var ? var->next : NULL); \
|
||||
var != NULL; \
|
||||
var = tmp, tmp = (var ? var->next : NULL) \
|
||||
)
|
||||
|
||||
#define LL_FOREACH_SAFE_IDX(head, var, tmp, idx) \
|
||||
for (typeof(head) var = (head), tmp = (var ? var->next : NULL); \
|
||||
var != NULL && ((idx) = 0, 1); \
|
||||
for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); \
|
||||
var != NULL; \
|
||||
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
|
||||
|
||||
#define LL_FOREACH_SAFE_IDX_LIMIT(head, var, tmp, idx, max) \
|
||||
|
Reference in New Issue
Block a user