Compare commits

..

6 Commits

Author SHA1 Message Date
a52dc89f9f diagdummy srpr2 wait for device lock 2025-11-24 22:29:59 +01:00
cc2b96f37a qemu_pci_serial device locking/sync 2025-11-24 22:29:32 +01:00
80a29d8ff6 Handle continous jobs via new subsystem - CJob 2025-11-24 21:53:51 +01:00
4f55d765b4 ulib Fix volatile 2025-11-24 17:14:45 +01:00
ec732d4627 Make SpinLock IRQ_CTX irq_flags volatile 2025-11-24 17:14:28 +01:00
3f3795df3c Fix stack alignment 2025-11-24 17:04:33 +01:00
16 changed files with 232 additions and 73 deletions

View File

@ -71,6 +71,7 @@ SRCFILES += $(call GRABSRC, \
pci \ pci \
pci/ata \ pci/ata \
pci/qemu_pci_serial \ pci/qemu_pci_serial \
cjob \
) )
CFILES := $(call GET_CFILES, $(SRCFILES)) 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 _push_regs
cld cld
movq %rsp, %rdi movq %rsp, %rdi
sub $0x8, %rsp
call intr_handleintr call intr_handleintr
add $0x8, %rsp
_pop_regs _pop_regs
add $0x10, %rsp add $0x10, %rsp
iretq iretq

View File

@ -7,15 +7,47 @@
#include "std/string.h" #include "std/string.h"
#include "dlmalloc/malloc.h" #include "dlmalloc/malloc.h"
#include "util/util.h" #include "util/util.h"
#include "cjob/cjob.h"
#include "hshtb.h" #include "hshtb.h"
#include "errors.h" #include "errors.h"
#include "kprintf.h" #include "kprintf.h"
IpcMBuses IPC_MBUSES; 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) { void ipc_mbusinit(void) {
memset(&IPC_MBUSES, 0, sizeof(IPC_MBUSES)); memset(&IPC_MBUSES, 0, sizeof(IPC_MBUSES));
spinlock_init(&IPC_MBUSES.spinlock); spinlock_init(&IPC_MBUSES.spinlock);
cjob_register(&ipc_mbus_gc_cjob, NULL);
} }
IpcMBus *ipc_mbusmake(const char *name, size_t objsize, size_t objmax) { 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; 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_mbusconsume(const char *name, uint8_t *const buffer, uint64_t pid);
int32_t ipc_mbusattch(const char *name, uint64_t pid); int32_t ipc_mbusattch(const char *name, uint64_t pid);
int32_t ipc_mbusdttch(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_ #endif // IPC_MBUS_MBUS_H_

View File

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

View File

@ -6,6 +6,8 @@
#include "sysdefs/dev.h" #include "sysdefs/dev.h"
#include "util/util.h" #include "util/util.h"
#include "dev/dev.h" #include "dev/dev.h"
#include "cjob/cjob.h"
#include "proc/proc.h"
#include "errors.h" #include "errors.h"
#include "hshtb.h" #include "hshtb.h"
#include "kprintf.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; (void)len; (void)pid;
QemuPciSerialDev *qpsd = dev->extra; QemuPciSerialDev *qpsd = dev->extra;
if (qpsd->lockstate != -1 && qpsd->lockstate != (int)pid) {
return E_DEVLOCKED;
}
_serial_sendb(qpsd->iobase, buffer[0]); _serial_sendb(qpsd->iobase, buffer[0]);
return E_OK; 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; (void)buffer; (void)len; (void)pid;
QemuPciSerialDev *qpsd = dev->extra; QemuPciSerialDev *qpsd = dev->extra;
if (qpsd->lockstate != -1 && qpsd->lockstate != (int)pid) {
return E_DEVLOCKED;
}
return _serial_sendready(qpsd->iobase); 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; (void)buffer; (void)len; (void)pid;
QemuPciSerialDev *qpsd = dev->extra; QemuPciSerialDev *qpsd = dev->extra;
if (qpsd->lockstate != -1 && qpsd->lockstate != (int)pid) {
return E_DEVLOCKED;
}
return _serial_recvb(qpsd->iobase); return _serial_recvb(qpsd->iobase);
} }
int32_t qemu_pci_serial_dev_recvready(struct Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) { 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; 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) { 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._magic = QEMU_PCI_SERIAL_MAGIC;
QEMU_PCI_SERIAL_DEV.iobase = iobase; QEMU_PCI_SERIAL_DEV.iobase = iobase;
QEMU_PCI_SERIAL_DEV.lockstate = -1;
Dev *serialdev = NULL; Dev *serialdev = NULL;
HSHTB_ALLOC(DEVTABLE.devs, ident, "serialdev", serialdev); 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[1] = &qemu_pci_serial_dev_sendready;
serialdev->fns[2] = &qemu_pci_serial_dev_recvb; serialdev->fns[2] = &qemu_pci_serial_dev_recvb;
serialdev->fns[3] = &qemu_pci_serial_dev_recvready; 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); spinlock_init(&serialdev->spinlock);
serialdev->extra = &QEMU_PCI_SERIAL_DEV; serialdev->extra = &QEMU_PCI_SERIAL_DEV;
cjob_register(&pci_qemu_pci_serial_gc_cjob, serialdev);
_serial_init(QEMU_PCI_SERIAL_DEV.iobase); _serial_init(QEMU_PCI_SERIAL_DEV.iobase);
} }

View File

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

View File

@ -19,6 +19,7 @@
#include "intr/pic.h" #include "intr/pic.h"
#include "vmm/vmm.h" #include "vmm/vmm.h"
#include "proc/switch.h" #include "proc/switch.h"
#include "cjob/cjob.h"
#include "elf.h" #include "elf.h"
#include "errors.h" #include "errors.h"
#include "kprintf.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); spinlock_acquire(&PROCS.spinlock);
Proc *head, *tmp; Proc *head, *tmp;
LL_FOREACH_SAFE(PROCS.procs, head, tmp) { LL_FOREACH_SAFE(PROCS.procs, head, tmp) {
@ -222,41 +249,12 @@ void proc_reaper(void) {
spinlock_release(&PROCS.spinlock); 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) { void proc_init(void) {
spinlock_init(&PROCS.spinlock); spinlock_init(&PROCS.spinlock);
PROCS.procs = NULL; PROCS.procs = NULL;
cjob_register(&proc_gc_cjob, NULL);
Proc *init = proc_spawnuser("base", "/bin/init"); Proc *init = proc_spawnuser("base", "/bin/init");
PROCS.current = init; PROCS.current = init;
proc_register(init); proc_register(init);

View File

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

View File

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

View File

@ -17,6 +17,8 @@
#define E_SPAWNERROR -13 #define E_SPAWNERROR -13
#define E_NOTYET -14 #define E_NOTYET -14
#define E_MOUNTERR -15 #define E_MOUNTERR -15
#define E_DEVLOCKED -16
#define E_DEVNOTYOURLOCK -17
#if !defined(__ASSEMBLER__) #if !defined(__ASSEMBLER__)
@ -38,6 +40,8 @@ static const char *_ERROR_STRINGS[] = {
"Process spawn error", "Process spawn error",
"Data isn't ready yet", "Data isn't ready yet",
"File system mount error", "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))) #define ERRSTRING_INDEX(ioh) ((size_t)((ioh) < 0 ? (ioh) * (-1) : (ioh)))

View File

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

View File

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

View File

@ -6,6 +6,8 @@
#define SENDREADY 1 #define SENDREADY 1
#define RECVB 2 #define RECVB 2
#define RECVREADY 3 #define RECVREADY 3
#define LOCK 4
#define UNLOCK 5
void diagdummy_srpr(void) { void diagdummy_srpr(void) {
char *str = "Hello world\n"; char *str = "Hello world\n";
@ -35,9 +37,13 @@ void diagdummy_srpr2(void) {
Dev_t serialdev; Dev_t serialdev;
dev_gethandle(&serialdev, "serialdev"); dev_gethandle(&serialdev, "serialdev");
while(dev_cmd(&serialdev, LOCK, NULL, 0) != E_OK);
for (;;) { for (;;) {
while (!dev_cmd(&serialdev, SENDREADY, NULL, 0)); while (!dev_cmd(&serialdev, SENDREADY, NULL, 0));
dev_cmd(&serialdev, SENDB, str, 1); dev_cmd(&serialdev, SENDB, str, 1);
schedsleep(500); schedsleep(500);
} }
dev_cmd(&serialdev, UNLOCK, NULL, 0);
} }