|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH 10/10] plat/xen/drivers/cons: Introduce Consfront Interrupt Handling
The current changes form interrupt handling for consfront.
Interrupt design is similar to virtio-net:
Keeps track if the user has enabled intr.
Enables only when rx is empty.
Read can not be called when intr are enabled.
Signed-off-by: Birlea Costin <costin.birlea@xxxxxxxxx>
---
plat/xen/drivers/cons/consfront.c | 61 +++++++++++++++++++++++++++++++++++++++
plat/xen/drivers/cons/consfront.h | 2 ++
2 files changed, 63 insertions(+)
diff --git a/plat/xen/drivers/cons/consfront.c
b/plat/xen/drivers/cons/consfront.c
index 6dd8a6f8..df233ea5 100644
--- a/plat/xen/drivers/cons/consfront.c
+++ b/plat/xen/drivers/cons/consfront.c
@@ -54,6 +54,12 @@
#define XEN_CONSFRONT_SIZE_IN 1024
#define XEN_CONSFRONT_SIZE_OUT 2048
+/* TODO Same interrupt macros we use in virtio-cons */
+#define CONSFRONT_INTR_EN (1 << 0)
+#define CONSFRONT_INTR_EN_MASK (1)
+#define CONSFRONT_INTR_USR_EN (1 << 1)
+#define CONSFRONT_INTR_USR_EN_MASK (2)
+
/* Get consfront_dev* which contains consdev */
#define to_consfront(dev) \
__containerof(dev, struct consfront_dev, consdev)
@@ -70,6 +76,7 @@ static void consfront_rx_handler(evtchn_port_t port __unused,
cfdev = to_consfront(dev);
UK_ASSERT(cfdev);
+ cfdev->intr_enabled &= ~(CONSFRONT_INTR_EN);
mask_evtchn(cfdev->evtchn);
uk_consdev_drv_rx_event(dev);
@@ -167,6 +174,7 @@ static int consfront_rx_configure(struct uk_consdev *dev,
/* Start with interrupts disabled, API user should enable them */
mask_evtchn(cfdev->evtchn);
+ cfdev->intr_enabled = 0;
return rc;
}
@@ -252,6 +260,54 @@ static int consfront_stop(struct uk_consdev *dev)
return 0;
}
+static int consfront_rx_intr_enable(struct uk_consdev *dev)
+{
+ struct xencons_interface *intf;
+ struct consfront_dev *cfdev;
+
+ UK_ASSERT(dev);
+
+ cfdev = to_consfront(dev);
+ UK_ASSERT(cfdev);
+
+ /* If the interrupt is enabled */
+ if (cfdev->intr_enabled & CONSFRONT_INTR_EN)
+ return 0;
+
+ intf = cfdev->ring;
+ UK_ASSERT(intf);
+
+ /**
+ * Enable the user configuration bit. This would cause the interrupt to
+ * be enabled automatically if the interrupt could not be enabled now
+ * due to data in the queue.
+ */
+ cfdev->intr_enabled = CONSFRONT_INTR_USR_EN;
+
+ /* Enable only if rx is empty */
+ if (intf->in_cons == intf->in_prod) {
+ cfdev->intr_enabled |= CONSFRONT_INTR_EN;
+ unmask_evtchn(cfdev->evtchn);
+ }
+
+ return 0;
+}
+
+static int consfront_rx_intr_disable(struct uk_consdev *dev)
+{
+ struct consfront_dev *cfdev;
+
+ UK_ASSERT(dev);
+
+ cfdev = to_consfront(dev);
+ UK_ASSERT(cfdev);
+
+ cfdev->intr_enabled &= ~(CONSFRONT_INTR_USR_EN | CONSFRONT_INTR_EN);
+ mask_evtchn(cfdev->evtchn);
+
+ return 0;
+}
+
static unsigned int pvconsole_output(struct consfront_dev *dev,
char *buf, unsigned int len)
{
@@ -358,6 +414,9 @@ static unsigned int consfront_read(struct uk_consdev *dev,
cfdev = to_consfront(dev);
UK_ASSERT(cfdev);
+ /* Queue interrupts have to be off when calling read */
+ UK_ASSERT(!(cfdev->intr_enabled & CONSFRONT_INTR_EN));
+
intf = cfdev->ring;
UK_ASSERT(intf);
@@ -407,6 +466,8 @@ static const struct uk_consdev_ops consfront_ops = {
.release = consfront_release,
.start = consfront_start,
.stop = consfront_stop,
+ .rx_intr_enable = consfront_rx_intr_enable,
+ .rx_intr_disable = consfront_rx_intr_disable,
.write = consfront_write,
.read = consfront_read,
.close = consfront_close,
diff --git a/plat/xen/drivers/cons/consfront.h
b/plat/xen/drivers/cons/consfront.h
index 61cb2df4..9360e95f 100644
--- a/plat/xen/drivers/cons/consfront.h
+++ b/plat/xen/drivers/cons/consfront.h
@@ -53,6 +53,8 @@ struct consfront_dev {
grant_ref_t ring_ref;
/* Event channel for the front ring. */
evtchn_port_t evtchn;
+ /* Flag for user interrupt enable */
+ uint8_t intr_enabled;
/* The consdev identifier */
__u16 uid;
};
--
2.11.0
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |