Compare commits
3 Commits
4f55d765b4
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| a52dc89f9f | |||
| cc2b96f37a | |||
| 80a29d8ff6 |
@ -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
36
kernel/cjob/cjob.c
Normal 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
29
kernel/cjob/cjob.h
Normal 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_
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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_
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
@ -63,6 +70,10 @@ int32_t qemu_pci_serial_dev_sendready(struct Dev *dev, uint8_t *buffer, size_t l
|
||||
|
||||
QemuPciSerialDev *qpsd = dev->extra;
|
||||
|
||||
if (qpsd->lockstate != -1 && qpsd->lockstate != (int)pid) {
|
||||
return E_DEVLOCKED;
|
||||
}
|
||||
|
||||
return _serial_sendready(qpsd->iobase);
|
||||
}
|
||||
|
||||
@ -71,17 +82,76 @@ int32_t qemu_pci_serial_dev_recvb(struct Dev *dev, uint8_t *buffer, size_t len,
|
||||
|
||||
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;
|
||||
|
||||
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) {
|
||||
PciDev dev = pci_getdev(0x1B36, 0x0002, -1);
|
||||
if (!dev.bits) {
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
typedef struct {
|
||||
uint32_t _magic;
|
||||
uint16_t iobase;
|
||||
int lockstate;
|
||||
} QemuPciSerialDev;
|
||||
|
||||
void pci_qemu_pci_serial_init(void);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)))
|
||||
|
||||
@ -6,6 +6,8 @@
|
||||
#define SENDREADY 1
|
||||
#define RECVB 2
|
||||
#define RECVREADY 3
|
||||
#define LOCK 4
|
||||
#define UNLOCK 5
|
||||
|
||||
void diagdummy_srpr(void) {
|
||||
char *str = "Hello world\n";
|
||||
@ -35,9 +37,13 @@ void diagdummy_srpr2(void) {
|
||||
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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user