Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/usermode Implement spl level based priority interru...



details:   https://anonhg.NetBSD.org/src/rev/3e71d46d1586
branches:  trunk
changeset: 769494:3e71d46d1586
user:      reinoud <reinoud%NetBSD.org@localhost>
date:      Mon Sep 12 12:24:34 2011 +0000

description:
Implement spl level based priority interrupt controller in software

diffstat:

 sys/arch/usermode/include/intr.h     |   4 +-
 sys/arch/usermode/usermode/intr.c    |  66 +++++++++++++++++++++++++++++++++--
 sys/arch/usermode/usermode/machdep.c |   5 +-
 3 files changed, 68 insertions(+), 7 deletions(-)

diffs (147 lines):

diff -r 8d9e1bea1b52 -r 3e71d46d1586 sys/arch/usermode/include/intr.h
--- a/sys/arch/usermode/include/intr.h  Mon Sep 12 12:11:53 2011 +0000
+++ b/sys/arch/usermode/include/intr.h  Mon Sep 12 12:24:34 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.h,v 1.3 2011/09/04 21:08:18 jmcneill Exp $ */
+/* $NetBSD: intr.h,v 1.4 2011/09/12 12:24:34 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -31,8 +31,10 @@
 
 #include <machine/intrdefs.h>
 
+void   splinit(void);
 int    splraise(int);
 void   spllower(int);
+void   spl_intr(int x, void (*func)(void *), void *arg);
 
 #define        spl0()          spllower(IPL_NONE)
 #define splx(x)                spllower(x)
diff -r 8d9e1bea1b52 -r 3e71d46d1586 sys/arch/usermode/usermode/intr.c
--- a/sys/arch/usermode/usermode/intr.c Mon Sep 12 12:11:53 2011 +0000
+++ b/sys/arch/usermode/usermode/intr.c Mon Sep 12 12:24:34 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.c,v 1.4 2011/09/08 11:13:03 jmcneill Exp $ */
+/* $NetBSD: intr.c,v 1.5 2011/09/12 12:24:34 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2011 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,14 +27,16 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.4 2011/09/08 11:13:03 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.5 2011/09/12 12:24:34 reinoud Exp $");
 
 #include <sys/types.h>
 
 #include <machine/intr.h>
 #include <machine/thunk.h>
 
-/* #define INTR_USE_SIGPROCMASK */
+//#define INTR_USE_SIGPROCMASK
+
+#define MAX_QUEUED_EVENTS 64
 
 static int usermode_x = IPL_NONE;
 
@@ -42,6 +44,46 @@
 static bool block_sigalrm = false;
 #endif
 
+
+struct spl_intr_event {
+       void (*func)(void *);
+       void *arg;
+};
+
+struct spl_intr_event spl_intrs[IPL_HIGH+1][MAX_QUEUED_EVENTS];
+int spl_intr_wr[IPL_HIGH+1];
+int spl_intr_rd[IPL_HIGH+1];
+
+void
+splinit(void)
+{
+       int i;
+       for (i = 0; i <= IPL_HIGH; i++) {
+               spl_intr_rd[i] = 1;
+               spl_intr_wr[i] = 1;
+       }
+}
+
+void
+spl_intr(int x, void (*func)(void *), void *arg)
+{
+       struct spl_intr_event *spli;
+
+       if (x >= usermode_x) {
+               func(arg);
+               return;
+       }
+
+       //printf("\nX : %d\n", x);
+       spli = &spl_intrs[x][spl_intr_wr[x]];
+       spli->func = func;
+       spli->arg = arg;
+
+       spl_intr_wr[x] = (spl_intr_wr[x] + 1) % MAX_QUEUED_EVENTS;
+       if (spl_intr_wr[x] == spl_intr_rd[x])
+               panic("%s: spl list %d full!\n", __func__, x);
+}
+
 int
 splraise(int x)
 {
@@ -64,8 +106,24 @@
 void
 spllower(int x)
 {
-       if (usermode_x > x)
+       struct spl_intr_event *spli;
+       int y;
+
+       /* `eat' interrupts that came by until we got back to x */
+       if (usermode_x > x) {
+               for (y = usermode_x; y >= x; y--) {
+                       while (spl_intr_rd[y] != spl_intr_wr[y]) {
+                               // printf("spl y %d firing\n", y);
+                               spli = &spl_intrs[y][spl_intr_rd[y]];
+                               if (!spli->func)
+                                       panic("%s: spli->func is NULL for ipl %d, rd %d, wr %d\n",
+                                               __func__, y, spl_intr_rd[y], spl_intr_wr[y]);
+                               spli->func(spli->arg);
+                               spl_intr_rd[y] = (spl_intr_rd[y] + 1) % MAX_QUEUED_EVENTS;
+                       }
+               }
                usermode_x = x;
+       }
 
 #ifdef INTR_USE_SIGPROCMASK
        if (x < IPL_SCHED && block_sigalrm) {
diff -r 8d9e1bea1b52 -r 3e71d46d1586 sys/arch/usermode/usermode/machdep.c
--- a/sys/arch/usermode/usermode/machdep.c      Mon Sep 12 12:11:53 2011 +0000
+++ b/sys/arch/usermode/usermode/machdep.c      Mon Sep 12 12:24:34 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.29 2011/09/09 20:06:04 reinoud Exp $ */
+/* $NetBSD: machdep.c,v 1.30 2011/09/12 12:24:34 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2011 Reinoud Zandijk <reinoud%netbsd.org@localhost>
@@ -32,7 +32,7 @@
 #include "opt_urkelvisor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.29 2011/09/09 20:06:04 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.30 2011/09/12 12:24:34 reinoud Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -113,6 +113,7 @@
        urkelvisor_init();
 #endif
 
+       splinit();
        splraise(IPL_HIGH);
 
        kernmain();



Home | Main Index | Thread Index | Old Index