ret_val = -EINVAL;
- if(proc && signal > 0 && signal <= SIGUNUSED) {
+ if(proc && signal >= 0 && signal <= SIGUNUSED) {
process_t *cproc;
stack_frame_t *kstk;
u32_t *vesp3;
cproc = process_get_current();
if(cproc != proc) {
+ dbg_printf("Signal %u to different process\n", signal);
/* FIXME: Need to suspend the process in order to deliver the signal safely */
process_suspend(proc);
return((void*)proc->p_sighandler[signal]);
}
-void _process_hwint_deliver(pid_t pid, int irq)
+int _process_hwint_deliver(pid_t pid, int irq)
{
process_t *proc;
+ int ret_val;
+ ret_val = -EINVAL;
proc = process_lookup(pid);
if(proc) {
process_signal_deliver(proc, SIGHWINT);
+ ret_val = 0;
}
- return;
+ return(ret_val);
}
#include <config.h>
#include <corax/types.h>
#include <corax/errno.h>
-#include <arch.h>
-#include <signal.h>
#include <sys/types.h>
#include <process.h>
+#include <signal.h>
+
+#include <arch.h>
+#include <debug.h>
struct intq {
pid_t handlers[CONFIG_IRQ_QLEN];
};
-struct intq _int_q[32];
+struct intq _int_q[IRQ(INT_MAX)];
-void _process_hwint_deliver(pid_t, int);
+int _process_hwint_deliver(pid_t, int);
-void _sig_hwint_deliver(const int irq)
+void _sig_hwint_deliver(const int intno)
{
struct intq *q;
+ int irq;
int i;
+ irq = IRQ(intno);
+
+ dbg_printf("Delivering interrupt %u\n", irq);
+
/* make sure we don't make invalid accesses to _int_q */
if(irq < 1 || irq >= (sizeof(_int_q) / sizeof(_int_q[0]))) {
return;
break;
}
+ dbg_printf("irq %u -> pid %u\n", irq, q->handlers[i]);
+
/* deliver hardware interrupt to process */
- _process_hwint_deliver(q->handlers[i], irq);
+ if(_process_hwint_deliver(q->handlers[i], irq) < 0) {
+ /* remove the handler if an interrupt could not be delivered */
+ pid_t npid;
+ int j;
+
+ dbg_printf("irq %u could not be delivered\n", irq);
+
+ for(npid = -1, j = (sizeof(q->handlers) / sizeof(q->handlers[0])) - 1; j > i; j++) {
+ if(q->handlers[j] > 0) {
+ npid = q->handlers[j];
+ q->handlers[j] = -1;
+ break;
+ }
+ }
+
+ q->handlers[i] = npid;
+ }
}
return;
struct sigaction *old;
process_t *cproc;
int ret_val;
+ int irq;
cproc = process_get_current();
case SIGHWINT:
/* this is the Corax way to notify processes about hardware interrupts */
+ for(irq = 0; irq < IRQ(INT_MAX); irq++) {
+ int intno;
+ pid_t cpid;
+
+ intno = INT(irq);
+ cpid = process_get_id(cproc);
+
+ if(sigismember(&(new.sa_mask), intno)) {
+ dbg_printf("Process %u would like to receive notifications for irq %u [%u]\n",
+ cpid, irq, intno);
+
+ _int_q[irq].handlers[0] = cpid;
+ }
+ }
+
ret_val = 0;
break;