diff options
author | Christian Mauderer <christian.mauderer@embedded-brains.de> | 2012-05-10 15:06:10 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2012-05-10 16:30:49 +0200 |
commit | ee6b343cbaa434d8c31a4d71dac5316b4404da35 (patch) | |
tree | 3ed32e5a8c1458207346eb0b203a2457ec109e44 /freebsd/kern/kern_intr.c | |
parent | Move rtems_bsd_thread0_ucred (diff) | |
download | rtems-libbsd-ee6b343cbaa434d8c31a4d71dac5316b4404da35.tar.bz2 |
Provide SWI(9) and TIMEOUT(9)
Diffstat (limited to '')
-rw-r--r-- | freebsd/kern/kern_intr.c | 87 |
1 files changed, 75 insertions, 12 deletions
diff --git a/freebsd/kern/kern_intr.c b/freebsd/kern/kern_intr.c index f93a72c6..982d5e82 100644 --- a/freebsd/kern/kern_intr.c +++ b/freebsd/kern/kern_intr.c @@ -55,19 +55,22 @@ __FBSDID("$FreeBSD$"); #include <freebsd/sys/sysctl.h> #include <freebsd/sys/syslog.h> #include <freebsd/sys/unistd.h> -#ifndef __rtems__ #include <freebsd/sys/vmmeter.h> -#endif /* __rtems__ */ #include <freebsd/machine/atomic.h> #include <freebsd/machine/cpu.h> #ifndef __rtems__ #include <freebsd/machine/md_var.h> #include <freebsd/machine/stdarg.h> +#else /* __rtems__ */ + #ifdef INTR_FILTER + #error INTR_FILTER is currently not suppported with RTEMS + #endif + #define RTEMSBSD_SWI_WAKEUP_EVENT RTEMS_EVENT_31 +#endif /* __rtems__ */ #ifdef DDB #include <freebsd/ddb/ddb.h> #include <freebsd/ddb/db_sym.h> #endif -#endif /* __rtems__ */ /* * Describe an interrupt thread. There is one of these per interrupt event. @@ -88,24 +91,27 @@ struct intr_entropy { }; struct intr_event *clk_intr_event; +#ifndef __rtems__ struct intr_event *tty_intr_event; void *vm_ih; +#endif /* __rtems__ */ struct proc *intrproc; static MALLOC_DEFINE(M_ITHREAD, "ithread", "Interrupt Threads"); static int intr_storm_threshold = 1000; +#ifndef __rtems__ TUNABLE_INT("hw.intr_storm_threshold", &intr_storm_threshold); SYSCTL_INT(_hw, OID_AUTO, intr_storm_threshold, CTLFLAG_RW, &intr_storm_threshold, 0, "Number of consecutive interrupts before storm protection is enabled"); +#endif /* __rtems__ */ static TAILQ_HEAD(, intr_event) event_list = TAILQ_HEAD_INITIALIZER(event_list); static struct mtx event_lock; MTX_SYSINIT(intr_event_list, &event_lock, "intr event list", MTX_DEF); static void intr_event_update(struct intr_event *ie); -#ifndef __rtems__ #ifdef INTR_FILTER static int intr_event_schedule_thread(struct intr_event *ie, struct intr_thread *ithd); @@ -117,7 +123,9 @@ static struct intr_thread *ithread_create(const char *name, static int intr_event_schedule_thread(struct intr_event *ie); static struct intr_thread *ithread_create(const char *name); #endif +#ifndef __rtems__ static void ithread_destroy(struct intr_thread *ithread); +#endif /* __rtems__ */ static void ithread_execute_handlers(struct proc *p, struct intr_event *ie); #ifdef INTR_FILTER @@ -125,7 +133,6 @@ static void priv_ithread_execute_handler(struct proc *p, struct intr_handler *ih); #endif static void ithread_loop(void *); -#endif /* __rtems__ */ static void ithread_update(struct intr_thread *ithd); #ifndef __rtems__ static void start_softintr(void *); @@ -172,6 +179,7 @@ intr_priority(enum intr_type flags) return pri; } +#endif /* __rtems__ */ /* * Update an ithread based on the associated intr_event. */ @@ -194,10 +202,13 @@ ithread_update(struct intr_thread *ithd) /* Update name and priority. */ strlcpy(td->td_name, ie->ie_fullname, sizeof(td->td_name)); thread_lock(td); +#ifndef __rtems__ sched_prio(td, pri); +#else /* __rtems__ */ +#warning TODO: set thread priority +#endif /* __rtems__ */ thread_unlock(td); } -#endif /* __rtems__ */ /* * Regenerate the full name of an interrupt event and update its priority. @@ -257,7 +268,6 @@ intr_event_update(struct intr_event *ie) ithread_update(ie->ie_thread); CTR2(KTR_INTR, "%s: updated %s", __func__, ie->ie_fullname); } -#ifndef __rtems__ int intr_event_create(struct intr_event **event, void *source, int flags, int irq, @@ -296,6 +306,7 @@ intr_event_create(struct intr_event **event, void *source, int flags, int irq, return (0); } +#ifndef __rtems__ /* * Bind an interrupt event to the specified CPU. Note that not all * platforms support binding an interrupt to a CPU. For those @@ -453,6 +464,7 @@ intr_event_destroy(struct intr_event *ie) return (0); } +#endif /* __rtems__ */ #ifndef INTR_FILTER static struct intr_thread * ithread_create(const char *name) @@ -469,15 +481,20 @@ ithread_create(const char *name) if (error) panic("kproc_create() failed with %d", error); thread_lock(td); +#ifndef __rtems__ sched_class(td, PRI_ITHD); TD_SET_IWAIT(td); +#endif /* __rtems__ */ thread_unlock(td); +#ifndef __rtems__ td->td_pflags |= TDP_ITHREAD; +#endif /* __rtems__ */ ithd->it_thread = td; CTR2(KTR_INTR, "%s: created %s", __func__, name); return (ithd); } #else +#ifndef __rtems__ static struct intr_thread * ithread_create(const char *name, struct intr_handler *ih) { @@ -501,7 +518,9 @@ ithread_create(const char *name, struct intr_handler *ih) CTR2(KTR_INTR, "%s: created %s", __func__, name); return (ithd); } +#endif /* __rtems__ */ #endif +#ifndef __rtems__ static void ithread_destroy(struct intr_thread *ithread) @@ -518,8 +537,8 @@ ithread_destroy(struct intr_thread *ithread) } thread_unlock(td); } -#endif /* __rtems__ */ +#endif /* __rtems__ */ #ifndef INTR_FILTER int intr_event_add_handler(struct intr_event *ie, const char *name, @@ -594,6 +613,7 @@ intr_event_add_handler(struct intr_event *ie, const char *name, return (0); } #else +#ifndef __rtems__ int intr_event_add_handler(struct intr_event *ie, const char *name, driver_filter_t filter, driver_intr_t handler, void *arg, u_char pri, @@ -675,6 +695,7 @@ intr_event_add_handler(struct intr_event *ie, const char *name, *cookiep = ih; return (0); } +#endif /* __rtems__ */ #endif #ifndef __rtems__ @@ -753,7 +774,9 @@ intr_handler_source(void *cookie) return (ie->ie_source); } +#endif /* __rtems__ */ #ifndef INTR_FILTER +#ifndef __rtems__ int intr_event_remove_handler(void *cookie) { @@ -843,6 +866,7 @@ ok: return (0); } +#endif /* __rtems__ */ static int intr_event_schedule_thread(struct intr_event *ie) { @@ -886,6 +910,7 @@ intr_event_schedule_thread(struct intr_event *ie) */ it->it_need = 1; thread_lock(td); +#ifndef __rtems__ if (TD_AWAITING_INTR(td)) { CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid, td->td_name); @@ -895,11 +920,19 @@ intr_event_schedule_thread(struct intr_event *ie) CTR5(KTR_INTR, "%s: pid %d (%s): it_need %d, state %d", __func__, p->p_pid, td->td_name, it->it_need, td->td_state); } +#else /* __rtems__ */ + /* Send event to wake the thread up. + * TODO: eventually replace event by a better mechanism + */ + rtems_status_code sc = rtems_event_send(td->td_id, RTEMSBSD_SWI_WAKEUP_EVENT); + BSD_ASSERT(sc == RTEMS_SUCCESSFUL); +#endif /* __rtems__ */ thread_unlock(td); return (0); } #else +#ifndef __rtems__ int intr_event_remove_handler(void *cookie) { @@ -1053,8 +1086,8 @@ intr_event_schedule_thread(struct intr_event *ie, struct intr_thread *it) return (0); } -#endif #endif /* __rtems__ */ +#endif /* * Allow interrupt event binding for software interrupt handlers -- a no-op, @@ -1099,19 +1132,20 @@ swi_add(struct intr_event **eventp, const char *name, driver_intr_t handler, (pri * RQ_PPQ) + PI_SOFT, flags, cookiep); if (error) return (error); +#ifndef __rtems__ if (pri == SWI_CLOCK) { struct proc *p; p = ie->ie_thread->it_thread->td_proc; PROC_LOCK(p); -#ifndef __rtems__ p->p_flag |= P_NOLOAD; -#endif /* __rtems__ */ PROC_UNLOCK(p); } +#else /* __rtems__ */ + // Do _not_ ignore the thread in the load avarage +#endif /* __rtems__ */ return (0); } -#ifndef __rtems__ /* * Schedule a software interrupt thread. */ @@ -1133,7 +1167,9 @@ swi_sched(void *cookie, int flags) atomic_store_rel_int(&ih->ih_need, 1); if (!(flags & SWI_DELAY)) { +#ifndef __rtems__ PCPU_INC(cnt.v_soft); +#endif /* __rtems__ */ #ifdef INTR_FILTER error = intr_event_schedule_thread(ie, ie->ie_thread); #else @@ -1143,6 +1179,7 @@ swi_sched(void *cookie, int flags) } } +#ifndef __rtems__ /* * Remove a software interrupt handler. Currently this code does not * remove the associated interrupt event if it becomes empty. Calling code @@ -1189,6 +1226,7 @@ priv_ithread_execute_handler(struct proc *p, struct intr_handler *ih) } #endif +#endif /* __rtems__ */ /* * This is a public function for use by drivers that mux interrupt * handlers for child devices from their interrupt handler. @@ -1245,12 +1283,17 @@ static void ithread_execute_handlers(struct proc *p, struct intr_event *ie) { +#ifndef __rtems__ /* Interrupt handlers should not sleep. */ if (!(ie->ie_flags & IE_SOFT)) THREAD_NO_SLEEPING(); intr_event_execute_handlers(p, ie); if (!(ie->ie_flags & IE_SOFT)) THREAD_SLEEPING_OK(); +#else /* __rtems__ */ + /* We only have soft-threads, so the two queries are not necessary. */ + intr_event_execute_handlers(p, ie); +#endif /* __rtems__ */ /* * Interrupt storm handling: @@ -1264,12 +1307,14 @@ ithread_execute_handlers(struct proc *p, struct intr_event *ie) */ if (intr_storm_threshold != 0 && ie->ie_count >= intr_storm_threshold && !(ie->ie_flags & IE_SOFT)) { +#ifndef __rtems__ /* Report the message only once every second. */ if (ppsratecheck(&ie->ie_warntm, &ie->ie_warncnt, 1)) { printf( "interrupt storm detected on \"%s\"; throttling interrupt source\n", ie->ie_name); } +#endif /* __rtems__ */ pause("istorm", 1); } else ie->ie_count++; @@ -1342,13 +1387,27 @@ ithread_loop(void *arg) */ thread_lock(td); if (!ithd->it_need && !(ithd->it_flags & IT_DEAD)) { +#ifndef __rtems__ TD_SET_IWAIT(td); ie->ie_count = 0; mi_switch(SW_VOL | SWT_IWAIT, NULL); +#else /* __rtems__ */ + /* wait for wakeup event + * TODO: eventually replace event by a better mechanism + */ + rtems_event_set event_out; + rtems_status_code sc = rtems_event_receive( + RTEMSBSD_SWI_WAKEUP_EVENT, + RTEMS_WAIT | RTEMS_EVENT_ALL, + RTEMS_NO_TIMEOUT, + &event_out); + BSD_ASSERT(sc == RTEMS_SUCCESSFUL); +#endif /* __rtems__ */ } thread_unlock(td); } } +#ifndef __rtems__ /* * Main interrupt handling body. @@ -1444,7 +1503,9 @@ intr_event_handle(struct intr_event *ie, struct trapframe *frame) td->td_intr_nesting_level--; return (0); } +#endif /* __rtems__ */ #else +#ifndef __rtems__ /* * This is the main code for interrupt threads. */ @@ -1647,7 +1708,9 @@ intr_event_handle(struct intr_event *ie, struct trapframe *frame) td->td_intr_nesting_level--; return (0); } +#endif /* __rtems__ */ #endif +#ifndef __rtems__ #ifdef DDB /* |