Compare commits

...

7 Commits

17 changed files with 251 additions and 75 deletions

View File

@ -71,6 +71,7 @@ SRCFILES += $(call GRABSRC, \
pci \
pci/ata \
pci/qemu_pci_serial \
cjob \
)
CFILES := $(call GET_CFILES, $(SRCFILES))

36
kernel/cjob/cjob.c Normal file
View File

@ -0,0 +1,36 @@
#include <stdint.h>
#include <stddef.h>
#include "spinlock/spinlock.h"
#include "cjob/cjob.h"
#include "dlmalloc/malloc.h"
#include "util/util.h"
CJobs CJOBS;
static uint64_t cjobids = 0;
void cjob_init(void) {
spinlock_init(&CJOBS.spinlock);
CJOBS.cjobs = NULL;
}
int32_t cjob_register(CJobFn fn, void *arg) {
CJob *cjob = dlmalloc(sizeof(*cjob));
cjob->fn = fn;
cjob->arg = arg;
int32_t id = cjob->id = cjobids++;
spinlock_acquire(&CJOBS.spinlock);
LL_APPEND(CJOBS.cjobs, cjob);
spinlock_release(&CJOBS.spinlock);
return id;
}
void cjob_runjobs(void) {
CJob *cjob, *cjobtmp;
spinlock_acquire(&CJOBS.spinlock);
LL_FOREACH_SAFE(CJOBS.cjobs, cjob, cjobtmp) {
cjob->fn(cjob->arg);
}
spinlock_release(&CJOBS.spinlock);
}

29
kernel/cjob/cjob.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef CJOB_CJOB_H_
#define CJOB_CJOB_H_
#include <stdint.h>
#include <stddef.h>
#include "spinlock/spinlock.h"
typedef void (*CJobFn)(void *arg);
typedef struct CJob {
struct CJob *next;
CJobFn fn;
void *arg;
int32_t id;
} CJob;
typedef struct {
SpinLock spinlock;
CJob *cjobs;
} CJobs;
extern CJobs CJOBS;
void cjob_init(void);
int32_t cjob_register(CJobFn fn, void *arg);
void cjob_runjobs(void);
#endif // CJOB_CJOB_H_

View File

@ -66,7 +66,9 @@
_push_regs
cld
movq %rsp, %rdi
sub $0x8, %rsp
call intr_handleintr
add $0x8, %rsp
_pop_regs
add $0x10, %rsp
iretq

View File

@ -7,15 +7,47 @@
#include "std/string.h"
#include "dlmalloc/malloc.h"
#include "util/util.h"
#include "cjob/cjob.h"
#include "hshtb.h"
#include "errors.h"
#include "kprintf.h"
IpcMBuses IPC_MBUSES;
void ipc_mbus_gc_cjob(void *arg) {
for (size_t i = 0; i < LEN(IPC_MBUSES.mbuses); i++) {
spinlock_acquire(&IPC_MBUSES.spinlock);
IpcMBus *mbus = &IPC_MBUSES.mbuses[i];
spinlock_release(&IPC_MBUSES.spinlock);
spinlock_acquire(&mbus->spinlock);
if (mbus->_hshtbstate != HSHTB_TAKEN) {
spinlock_release(&mbus->spinlock);
continue;
}
IpcMBusCons *cons, *constmp;
LL_FOREACH_SAFE(mbus->consumers, cons, constmp) {
spinlock_acquire(&PROCS.spinlock);
Proc *proc = NULL;
LL_FINDPROP(PROCS.procs, proc, pid, cons->pid);
spinlock_release(&PROCS.spinlock);
if (proc == NULL) {
LL_REMOVE(mbus->consumers, cons);
dlfree(cons->rbuf.buffer);
dlfree(cons);
}
}
spinlock_release(&mbus->spinlock);
}
}
void ipc_mbusinit(void) {
memset(&IPC_MBUSES, 0, sizeof(IPC_MBUSES));
spinlock_init(&IPC_MBUSES.spinlock);
cjob_register(&ipc_mbus_gc_cjob, NULL);
}
IpcMBus *ipc_mbusmake(const char *name, size_t objsize, size_t objmax) {
@ -174,32 +206,3 @@ int32_t ipc_mbusdttch(const char *name, uint64_t pid) {
return E_OK;
}
void ipc_mbustick(void) {
for (size_t i = 0; i < LEN(IPC_MBUSES.mbuses); i++) {
spinlock_acquire(&IPC_MBUSES.spinlock);
IpcMBus *mbus = &IPC_MBUSES.mbuses[i];
spinlock_release(&IPC_MBUSES.spinlock);
spinlock_acquire(&mbus->spinlock);
if (mbus->_hshtbstate != HSHTB_TAKEN) {
spinlock_release(&mbus->spinlock);
continue;
}
IpcMBusCons *cons, *constmp;
LL_FOREACH_SAFE(mbus->consumers, cons, constmp) {
spinlock_acquire(&PROCS.spinlock);
Proc *proc = NULL;
LL_FINDPROP(PROCS.procs, proc, pid, cons->pid);
spinlock_release(&PROCS.spinlock);
if (proc == NULL) {
LL_REMOVE(mbus->consumers, cons);
dlfree(cons->rbuf.buffer);
dlfree(cons);
}
}
spinlock_release(&mbus->spinlock);
}
}

View File

@ -34,6 +34,5 @@ int32_t ipc_mbuspublish(const char *name, const uint8_t *const buffer);
int32_t ipc_mbusconsume(const char *name, uint8_t *const buffer, uint64_t pid);
int32_t ipc_mbusattch(const char *name, uint64_t pid);
int32_t ipc_mbusdttch(const char *name, uint64_t pid);
void ipc_mbustick(void);
#endif // IPC_MBUS_MBUS_H_

View File

@ -19,6 +19,7 @@
#include "cpu/gdt.h"
#include "ipc/mbus/mbus.h"
#include "pci/pci.h"
#include "cjob/cjob.h"
void log_bootinfo(void) {
char buf[100];
@ -50,6 +51,7 @@ void kmain(void) {
vmm_init();
intr_init();
randcrypto_init();
cjob_init();
ipc_mbusinit();
dev_init();
storedev_init();

View File

@ -6,6 +6,8 @@
#include "sysdefs/dev.h"
#include "util/util.h"
#include "dev/dev.h"
#include "cjob/cjob.h"
#include "proc/proc.h"
#include "errors.h"
#include "hshtb.h"
#include "kprintf.h"
@ -53,6 +55,11 @@ int32_t qemu_pci_serial_dev_sendb(struct Dev *dev, uint8_t *buffer, size_t len,
(void)len; (void)pid;
QemuPciSerialDev *qpsd = dev->extra;
if (qpsd->lockstate != -1 && qpsd->lockstate != (int)pid) {
return E_DEVLOCKED;
}
_serial_sendb(qpsd->iobase, buffer[0]);
return E_OK;
@ -62,6 +69,10 @@ int32_t qemu_pci_serial_dev_sendready(struct Dev *dev, uint8_t *buffer, size_t l
(void)buffer; (void)len; (void)pid;
QemuPciSerialDev *qpsd = dev->extra;
if (qpsd->lockstate != -1 && qpsd->lockstate != (int)pid) {
return E_DEVLOCKED;
}
return _serial_sendready(qpsd->iobase);
}
@ -70,16 +81,75 @@ int32_t qemu_pci_serial_dev_recvb(struct Dev *dev, uint8_t *buffer, size_t len,
(void)buffer; (void)len; (void)pid;
QemuPciSerialDev *qpsd = dev->extra;
if (qpsd->lockstate != -1 && qpsd->lockstate != (int)pid) {
return E_DEVLOCKED;
}
return _serial_recvb(qpsd->iobase);
}
int32_t qemu_pci_serial_dev_recvready(struct Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) {
(void)dev; (void)buffer; (void)len; (void)pid;
(void)buffer; (void)len; (void)pid;
QemuPciSerialDev *qpsd = dev->extra;
if (qpsd->lockstate != -1 && qpsd->lockstate != (int)pid) {
return E_DEVLOCKED;
}
return _serial_recvready(qpsd->iobase);
}
int32_t qemu_pci_serial_dev_lock(struct Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) {
(void)buffer; (void)len; (void)pid;
QemuPciSerialDev *qpsd = dev->extra;
return _serial_recvready(qpsd->iobase);
if (qpsd->lockstate == (int)pid) {
return E_OK;
}
if (qpsd->lockstate == -1) {
qpsd->lockstate = (int)pid;
return E_OK;
}
return E_DEVLOCKED;
}
int32_t qemu_pci_serial_dev_unlock(struct Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) {
(void)buffer; (void)len; (void)pid;
QemuPciSerialDev *qpsd = dev->extra;
if (qpsd->lockstate == (int)pid) {
qpsd->lockstate = -1;
return E_OK;
}
return E_DEVNOTYOURLOCK;
}
void pci_qemu_pci_serial_gc_cjob(void *arg) {
Dev *dev = arg;
QemuPciSerialDev *qpsd;
spinlock_acquire(&dev->spinlock);
qpsd = dev->extra;
uint64_t pid = qpsd->lockstate;
spinlock_release(&dev->spinlock);
Proc *proc = NULL;
spinlock_acquire(&PROCS.spinlock);
LL_FINDPROP(PROCS.procs, proc, pid, pid);
spinlock_release(&PROCS.spinlock);
if (proc == NULL) {
spinlock_acquire(&dev->spinlock);
qpsd = dev->extra;
qpsd->lockstate = -1;
spinlock_release(&dev->spinlock);
}
}
void pci_qemu_pci_serial_init(void) {
@ -97,6 +167,7 @@ void pci_qemu_pci_serial_init(void) {
QEMU_PCI_SERIAL_DEV._magic = QEMU_PCI_SERIAL_MAGIC;
QEMU_PCI_SERIAL_DEV.iobase = iobase;
QEMU_PCI_SERIAL_DEV.lockstate = -1;
Dev *serialdev = NULL;
HSHTB_ALLOC(DEVTABLE.devs, ident, "serialdev", serialdev);
@ -104,8 +175,13 @@ void pci_qemu_pci_serial_init(void) {
serialdev->fns[1] = &qemu_pci_serial_dev_sendready;
serialdev->fns[2] = &qemu_pci_serial_dev_recvb;
serialdev->fns[3] = &qemu_pci_serial_dev_recvready;
serialdev->fns[4] = &qemu_pci_serial_dev_lock;
serialdev->fns[5] = &qemu_pci_serial_dev_unlock;
spinlock_init(&serialdev->spinlock);
serialdev->extra = &QEMU_PCI_SERIAL_DEV;
cjob_register(&pci_qemu_pci_serial_gc_cjob, serialdev);
_serial_init(QEMU_PCI_SERIAL_DEV.iobase);
}

View File

@ -9,6 +9,7 @@
typedef struct {
uint32_t _magic;
uint16_t iobase;
int lockstate;
} QemuPciSerialDev;
void pci_qemu_pci_serial_init(void);

View File

@ -19,6 +19,7 @@
#include "intr/pic.h"
#include "vmm/vmm.h"
#include "proc/switch.h"
#include "cjob/cjob.h"
#include "elf.h"
#include "errors.h"
#include "kprintf.h"
@ -174,7 +175,33 @@ Proc *proc_nextready(void) {
}
}
void proc_reaper(void) {
void proc_sched(void *cpustate) {
intr_disable();
memcpy(&PROCS.current->platformdata.trapframe, cpustate, sizeof(IntrStackFrame));
PROCS.current = proc_nextready();
cjob_runjobs();
tss.rsp0 = (uint64_t)VIRT(PROCS.current->platformdata.kstack);
proc_switch(&PROCS.current->platformdata.trapframe, (void *)PROCS.current->platformdata.cr3);
}
void proc_kill(Proc *proc) {
spinlock_acquire(&PROCS.spinlock);
proc->state = PROC_ZOMBIE;
spinlock_release(&PROCS.spinlock);
}
void proc_killself(void) {
spinlock_acquire(&PROCS.spinlock);
Proc *proc = PROCS.current;
spinlock_release(&PROCS.spinlock);
proc_kill(proc);
}
void proc_gc_cjob(void *arg) {
spinlock_acquire(&PROCS.spinlock);
Proc *head, *tmp;
LL_FOREACH_SAFE(PROCS.procs, head, tmp) {
@ -222,41 +249,12 @@ void proc_reaper(void) {
spinlock_release(&PROCS.spinlock);
}
void proc_tick(void) {
proc_reaper();
ipc_mbustick();
}
void proc_sched(void *cpustate) {
intr_disable();
memcpy(&PROCS.current->platformdata.trapframe, cpustate, sizeof(IntrStackFrame));
PROCS.current = proc_nextready();
proc_tick();
tss.rsp0 = (uint64_t)VIRT(PROCS.current->platformdata.kstack);
proc_switch(&PROCS.current->platformdata.trapframe, (void *)PROCS.current->platformdata.cr3);
}
void proc_kill(Proc *proc) {
spinlock_acquire(&PROCS.spinlock);
proc->state = PROC_ZOMBIE;
spinlock_release(&PROCS.spinlock);
}
void proc_killself(void) {
spinlock_acquire(&PROCS.spinlock);
Proc *proc = PROCS.current;
spinlock_release(&PROCS.spinlock);
proc_kill(proc);
}
void proc_init(void) {
spinlock_init(&PROCS.spinlock);
PROCS.procs = NULL;
cjob_register(&proc_gc_cjob, NULL);
Proc *init = proc_spawnuser("base", "/bin/init");
PROCS.current = init;
proc_register(init);

View File

@ -2,10 +2,7 @@
.global proc_switch
proc_switch:
testq %rsi, %rsi
je 1f
movq %rsi, %cr3
1:
mov %rdi, %rsp
_pop_regs
add $0x10, %rsp

View File

@ -6,8 +6,8 @@
#define SPINLOCK_HINT() asm volatile("pause")
struct {
uint64_t irq_flags;
static struct {
volatile uint64_t irq_flags;
atomic_int irq_nest;
} IRQ_CTX = {0};

View File

@ -17,6 +17,8 @@
#define E_SPAWNERROR -13
#define E_NOTYET -14
#define E_MOUNTERR -15
#define E_DEVLOCKED -16
#define E_DEVNOTYOURLOCK -17
#if !defined(__ASSEMBLER__)
@ -38,6 +40,8 @@ static const char *_ERROR_STRINGS[] = {
"Process spawn error",
"Data isn't ready yet",
"File system mount error",
"This device is locked",
"Device is hasn't been locked by this process",
};
#define ERRSTRING_INDEX(ioh) ((size_t)((ioh) < 0 ? (ioh) * (-1) : (ioh)))

View File

@ -9,8 +9,8 @@
#include <umalloc/umalloc.h>
extern void main(void);
extern uint8_t _bss_start[];
extern uint8_t _bss_end[];
extern volatile uint8_t _bss_start[];
extern volatile uint8_t _bss_end[];
void clearbss(void) {
uint8_t *p = _bss_start;
@ -20,7 +20,7 @@ void clearbss(void) {
}
#define MAX_ARGS 25
static char *_args[MAX_ARGS];
static volatile char *_args[MAX_ARGS];
size_t _argslen;
@ -40,7 +40,7 @@ void _premain(void) {
_args[i] = umalloc(PROC_ARG_MAX);
}
proc_argv(-1, &_argslen, _args, MAX_ARGS);
proc_argv(-1, &_argslen, (char **)_args, MAX_ARGS);
main();
proc_kill(proc_getpid());

View File

@ -4,4 +4,9 @@
.global _start
_start:
xor %rbp, %rbp
mov %rsp, %rbp
and $-0x10, %rsp
sub $0x8, %rsp
call _premain

View File

@ -2,7 +2,7 @@
#define CMDS(X) \
X(block) X(openf) \
X(serialprint)
X(srpr) X(srpr2) \
void main(void) {
if (argslen() == 0) {

View File

@ -6,8 +6,10 @@
#define SENDREADY 1
#define RECVB 2
#define RECVREADY 3
#define LOCK 4
#define UNLOCK 5
void diagdummy_serialprint(void) {
void diagdummy_srpr(void) {
char *str = "Hello world\n";
if (argslen() >= 2) {
@ -24,3 +26,24 @@ void diagdummy_serialprint(void) {
s++;
}
}
void diagdummy_srpr2(void) {
if (argslen() < 2) {
return;
}
char *str = args()[1];
Dev_t serialdev;
dev_gethandle(&serialdev, "serialdev");
while(dev_cmd(&serialdev, LOCK, NULL, 0) != E_OK);
for (;;) {
while (!dev_cmd(&serialdev, SENDREADY, NULL, 0));
dev_cmd(&serialdev, SENDB, str, 1);
schedsleep(500);
}
dev_cmd(&serialdev, UNLOCK, NULL, 0);
}