bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v11 2/2 hurd] ddekit: Use libirqhelp for interrupt registration


From: Damien Zammit
Subject: [PATCH v11 2/2 hurd] ddekit: Use libirqhelp for interrupt registration
Date: Sun, 24 Mar 2024 10:08:39 +0000

Use the new irqhelp library in ddekit and clean up.

---
 libddekit/Makefile    |   2 +-
 libddekit/interrupt.c | 214 ++++++------------------------------------
 2 files changed, 31 insertions(+), 185 deletions(-)

diff --git a/libddekit/Makefile b/libddekit/Makefile
index 88a0c8909..c74ec1128 100644
--- a/libddekit/Makefile
+++ b/libddekit/Makefile
@@ -39,7 +39,7 @@ LCLHDRS = $(installhdrs)      \
 
 OBJS = $(sort $(SRCS:.c=.o))
 
-HURDLIBS = ports shouldbeinlibc hurd-slab
+HURDLIBS = ports shouldbeinlibc hurd-slab irqhelp
 LDLIBS += -lpthread
 
 MIGCOMSFLAGS = -prefix dde_
diff --git a/libddekit/interrupt.c b/libddekit/interrupt.c
index 35f95a68c..17c550876 100644
--- a/libddekit/interrupt.c
+++ b/libddekit/interrupt.c
@@ -4,8 +4,6 @@
  * \author  Christian Helmuth <ch12@os.inf.tu-dresden.de>
  * \date    2007-01-22
  *
- * FIXME could intloop_param freed after startup?
- * FIXME use consume flag to indicate IRQ was handled
  */
 
 #include <stdio.h>
@@ -13,153 +11,24 @@
 #include <mach.h>
 #include <hurd.h>
 
-#include <device/notify.h>
-#include <device/device.h>
+#include "libirqhelp/irqhelp.h"
 
-#include "ddekit/interrupt.h"
 #include "ddekit/semaphore.h"
+#include "ddekit/thread.h"
+#include "ddekit/interrupt.h"
 #include "ddekit/printf.h"
-#include "ddekit/memory.h"
-#include "ddekit/condvar.h"
-
-#define DEBUG_INTERRUPTS  0
 
 #define MAX_INTERRUPTS   32
 
-#define BLOCK_IRQ         0
-
-/*
- * Internal type for interrupt loop parameters
- */
-struct intloop_params
-{
-       unsigned          irq;       /* irq number */
-       int               shared;    /* irq sharing supported? */
-       void(*thread_init)(void *);  /* thread initialization */
-       void(*handler)(void *);      /* IRQ handler function */
-       void             *priv;      /* private token */ 
-       mach_port_t       irqport;   /* delivery port for notifications */
-       ddekit_sem_t     *started;
-
-       int               start_err;
-};
-
 static struct
 {
        int              handle_irq; /* nested irq disable count */
        ddekit_lock_t    irqlock;
-       struct ddekit_condvar   *cond;
-       ddekit_thread_t  *irq_thread; /* thread ID for detaching from IRQ later 
on */
-       boolean_t        thread_exit;
-       thread_t         mach_thread;
+       ddekit_thread_t  *irq_thread;
+       ddekit_sem_t     *started;
+       void             *irqhelp;   /* irqhelp instance for detaching from IRQ 
*/
 } ddekit_irq_ctrl[MAX_INTERRUPTS];
 
-static mach_port_t master_host;
-static mach_port_t master_device;
-static device_t irq_dev;
-
-/**
- * Interrupt service loop
- *
- */
-static void intloop(void *arg)
-{
-       kern_return_t ret;
-       struct intloop_params *params = arg;
-       mach_port_t delivery_port;
-       mach_port_t pset, psetcntl;
-       int my_index;
-
-       ret = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
-                                 &delivery_port);
-       if (ret)
-         error (2, ret, "mach_port_allocate");
-
-       my_index = params->irq;
-       params->irqport = delivery_port;
-       ddekit_irq_ctrl[my_index].mach_thread = mach_thread_self ();
-       ret = thread_get_assignment (mach_thread_self (), &pset);
-       if (ret)
-               error (0, ret, "thread_get_assignment");
-       ret = host_processor_set_priv (master_host, pset, &psetcntl);
-       if (ret)
-               error (0, ret, "host_processor_set_priv");
-       thread_max_priority (mach_thread_self (), psetcntl, 0);
-       ret = thread_priority (mach_thread_self (), DDEKIT_IRQ_PRIO, 0);
-       if (ret)
-               error (0, ret, "thread_priority");
-
-       // TODO the flags for shared irq should be indicated by params->shared.
-       // Flags needs to be 0 for new irq interface for now.
-       // Otherwise, the interrupt handler cannot be installed in the kernel.
-       ret = device_intr_register (irq_dev, my_index,
-                                 0, delivery_port,
-                                 MACH_MSG_TYPE_MAKE_SEND);
-       ddekit_printf ("device_intr_register returns %d\n", ret);
-       if (ret) {
-               /* inform thread creator of error */
-               /* XXX does omega0 error code have any meaning to DDEKit users? 
*/
-               params->start_err = ret;
-               ddekit_sem_up(params->started);
-               ddekit_printf ("cannot install irq %d\n", my_index);
-               return;
-       }
-
-#if 0
-       /* 
-        * Setup an exit fn. This will make sure that we clean up everything,
-        * before shutting down an IRQ thread.
-        */
-       if (l4thread_on_exit(&exit_fn, (void *)my_index) < 0)
-               ddekit_panic("Could not set exit handler for IRQ fn.");
-#endif
-
-       /* after successful initialization call thread_init() before doing 
anything
-        * else here */
-       if (params->thread_init) params->thread_init(params->priv);
-
-       /* save handle + inform thread creator of success */
-       params->start_err = 0;
-       ddekit_sem_up(params->started);
-
-       int irq_server (mach_msg_header_t *inp, mach_msg_header_t *outp) {
-               device_intr_notification_t *intr_header = 
(device_intr_notification_t *) inp;
-
-               ((mig_reply_header_t *) outp)->RetCode = MIG_NO_REPLY;
-               if (inp->msgh_id != DEVICE_INTR_NOTIFY)
-                       return 0;
-
-               /* It's an interrupt not for us. It shouldn't happen. */
-               if (intr_header->id != params->irq) {
-                       ddekit_printf ("We get interrupt %d, %d is expected",
-                                      intr_header->id, params->irq);
-                       return 1;
-               }
-
-               /* only call registered handler function, if IRQ is not 
disabled */
-               ddekit_lock_lock (&ddekit_irq_ctrl[my_index].irqlock);
-               while (ddekit_irq_ctrl[my_index].handle_irq <= 0) {
-                       ddekit_condvar_wait (ddekit_irq_ctrl[my_index].cond,
-                                       &ddekit_irq_ctrl[my_index].irqlock);
-                       // TODO if it's edged-triggered irq, the interrupt will 
be lost.
-               }
-               params->handler(params->priv);
-
-               /* Acknowledge the interrupt */
-               device_intr_ack (irq_dev, params->irqport, 
MACH_MSG_TYPE_MAKE_SEND);
-
-               if (ddekit_irq_ctrl[my_index].thread_exit) {
-                       ddekit_lock_unlock (&ddekit_irq_ctrl[my_index].irqlock);
-                       ddekit_thread_exit();
-                       return 1;
-               }
-               ddekit_lock_unlock (&ddekit_irq_ctrl[my_index].irqlock);
-               return 1;
-       }
-
-       mach_msg_server (irq_server, 0, delivery_port);
-}
-
 
 /**
  * Attach to hardware interrupt
@@ -178,53 +47,43 @@ ddekit_thread_t *ddekit_interrupt_attach(int irq, int 
shared,
                                          void(*thread_init)(void *),
                                          void(*handler)(void *), void *priv)
 {
-       struct intloop_params *params;
        ddekit_thread_t *thread;
        char thread_name[10];
 
        /* We cannot attach the interrupt to the irq which has been used. */
        if (ddekit_irq_ctrl[irq].irq_thread)
-         return NULL;
-
-       /* initialize info structure for interrupt loop */
-       params = ddekit_simple_malloc(sizeof(*params));
-       if (!params) return NULL;
+               return NULL;
 
-       // TODO make sure irq is 0-15 instead of 1-16.
-       params->irq         = irq;
-       params->thread_init = thread_init;
-       params->handler     = handler;
-       params->priv        = priv;
-       params->started     = ddekit_sem_init(0);
-       params->start_err   = 0;
-       params->irqport     = MACH_PORT_NULL;
-       params->shared      = shared;
+       ddekit_irq_ctrl[irq].started = ddekit_sem_init(0);
+       ddekit_irq_ctrl[irq].handle_irq = 1; /* IRQ initial nesting is 1 */
+       ddekit_lock_init_unlocked (&ddekit_irq_ctrl[irq].irqlock);
 
        /* construct name */
-       snprintf(thread_name, 10, "irq%02X", irq);
+       snprintf(thread_name, sizeof(thread_name), "irq%02X", irq);
 
-       ddekit_irq_ctrl[irq].handle_irq = 1; /* IRQ nesting level is initially 
1 */
-       ddekit_lock_init_unlocked (&ddekit_irq_ctrl[irq].irqlock);
-       ddekit_irq_ctrl[irq].cond = ddekit_condvar_init ();
-       ddekit_irq_ctrl[irq].thread_exit = FALSE;
+       ddekit_irq_ctrl[irq].irqhelp = irqhelp_install_interrupt_handler(irq, 
-1, -1, -1, handler, priv);
+
+       void wrapped_server_loop(void *arg)
+       {
+               struct irq *irqhelp = ddekit_irq_ctrl[irq].irqhelp;
+
+               thread_init(arg);
+               ddekit_sem_up(ddekit_irq_ctrl[irq].started);
+
+               irqhelp_server_loop(irqhelp);
+       }
 
-       /* allocate irq */
        /* create interrupt loop thread */
-       thread = ddekit_thread_create(intloop, params, thread_name);
+       thread = ddekit_thread_create(wrapped_server_loop, priv, thread_name);
        if (!thread) {
-               ddekit_simple_free(params);
+               irqhelp_remove_interrupt_handler(ddekit_irq_ctrl[irq].irqhelp);
                return NULL;
        }
        ddekit_irq_ctrl[irq].irq_thread = thread;
 
-
        /* wait for intloop initialization result */
-       ddekit_sem_down(params->started);
-       ddekit_sem_deinit(params->started);
-       if (params->start_err) {
-               ddekit_simple_free(params);
-               return NULL;
-       }
+       ddekit_sem_down(ddekit_irq_ctrl[irq].started);
+       ddekit_sem_deinit(ddekit_irq_ctrl[irq].started);
 
        return thread;
 }
@@ -236,16 +95,11 @@ ddekit_thread_t *ddekit_interrupt_attach(int irq, int 
shared,
 void ddekit_interrupt_detach(int irq)
 {
        ddekit_interrupt_disable(irq);
-       // TODO  the code should be removed.
+
        ddekit_lock_lock (&ddekit_irq_ctrl[irq].irqlock);
        if (ddekit_irq_ctrl[irq].handle_irq == 0) {
-               ddekit_irq_ctrl[irq].thread_exit = TRUE;
+               irqhelp_remove_interrupt_handler(ddekit_irq_ctrl[irq].irqhelp);
                ddekit_irq_ctrl[irq].irq_thread = NULL;
-
-               /* If the irq thread is waiting for interrupt notification
-                * messages, thread_abort() can force it to return.
-                * I hope this ugly trick can work. */
-               thread_abort (ddekit_irq_ctrl[irq].mach_thread);
        }
        ddekit_lock_unlock (&ddekit_irq_ctrl[irq].irqlock);
 }
@@ -267,20 +121,12 @@ void ddekit_interrupt_enable(int irq)
                ddekit_lock_lock (&ddekit_irq_ctrl[irq].irqlock);
                ++ddekit_irq_ctrl[irq].handle_irq;
                if (ddekit_irq_ctrl[irq].handle_irq > 0)
-                       ddekit_condvar_signal (ddekit_irq_ctrl[irq].cond);
+                       irqhelp_enable_irq(ddekit_irq_ctrl[irq].irqhelp);
                ddekit_lock_unlock (&ddekit_irq_ctrl[irq].irqlock);
        }
 }
 
 void interrupt_init (void)
 {
-       error_t err;
-
-       err = get_privileged_ports (&master_host, &master_device);
-       if (err)
-               error (1, err, "get_privileged_ports");
-
-       err = device_open (master_device, D_READ, "irq", &irq_dev);
-       if (err)
-               error (2, err, "device_open irq");
+       irqhelp_init();
 }
-- 
2.43.0





reply via email to

[Prev in Thread] Current Thread [Next in Thread]