Compare commits

..

2 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
4 changed files with 89 additions and 2 deletions

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

@ -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

@ -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);
} }