Compare commits
2 Commits
80a29d8ff6
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| a52dc89f9f | |||
| cc2b96f37a |
@ -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;
|
||||||
@ -63,6 +70,10 @@ int32_t qemu_pci_serial_dev_sendready(struct Dev *dev, uint8_t *buffer, size_t l
|
|||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,17 +82,76 @@ int32_t qemu_pci_serial_dev_recvb(struct Dev *dev, uint8_t *buffer, size_t len,
|
|||||||
|
|
||||||
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;
|
QemuPciSerialDev *qpsd = dev->extra;
|
||||||
|
|
||||||
|
if (qpsd->lockstate != -1 && qpsd->lockstate != (int)pid) {
|
||||||
|
return E_DEVLOCKED;
|
||||||
|
}
|
||||||
|
|
||||||
return _serial_recvready(qpsd->iobase);
|
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) {
|
void pci_qemu_pci_serial_init(void) {
|
||||||
PciDev dev = pci_getdev(0x1B36, 0x0002, -1);
|
PciDev dev = pci_getdev(0x1B36, 0x0002, -1);
|
||||||
if (!dev.bits) {
|
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._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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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)))
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user