diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2019-07-25 10:20:19 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2019-09-23 10:55:49 +0200 |
commit | 989e2dd76e3d2411d6ac79cd426d340939ad1bb9 (patch) | |
tree | ad34fbc6c89900f674bef93da92d6f5540614cec | |
parent | nexus: Avoid NULL pointer access (diff) | |
download | rtems-libbsd-989e2dd76e3d2411d6ac79cd426d340939ad1bb9.tar.bz2 |
CONFIG_INTRHOOK(9): Call handlers after boot
This enables adding drivers on demand which use this service after
initialization.
-rw-r--r-- | freebsd/sys/kern/subr_autoconf.c | 16 | ||||
-rw-r--r-- | testsuite/swi01/swi_test.c | 34 |
2 files changed, 45 insertions, 5 deletions
diff --git a/freebsd/sys/kern/subr_autoconf.c b/freebsd/sys/kern/subr_autoconf.c index 33087b03..39332214 100644 --- a/freebsd/sys/kern/subr_autoconf.c +++ b/freebsd/sys/kern/subr_autoconf.c @@ -63,6 +63,9 @@ static TAILQ_HEAD(, intr_config_hook) intr_config_hook_list = static struct intr_config_hook *next_to_notify; static struct mtx intr_config_hook_lock; MTX_SYSINIT(intr_config_hook, &intr_config_hook_lock, "intr config", MTX_DEF); +#ifdef __rtems__ +static bool intr_boot_done; +#endif /* __rtems__ */ /* ARGSUSED */ static void run_interrupt_driven_config_hooks(void); @@ -174,6 +177,9 @@ boot_run_interrupt_driven_config_hooks(void *dummy) mtx_lock(&intr_config_hook_lock); } } +#ifdef __rtems__ + intr_boot_done = true; +#endif /* __rtems__ */ mtx_unlock(&intr_config_hook_lock); TSUNWAIT("config hooks"); } @@ -190,6 +196,9 @@ int config_intrhook_establish(struct intr_config_hook *hook) { struct intr_config_hook *hook_entry; +#ifdef __rtems__ + bool run; +#endif /* __rtems__ */ TSHOLD("config hooks"); mtx_lock(&intr_config_hook_lock); @@ -205,16 +214,21 @@ config_intrhook_establish(struct intr_config_hook *hook) TAILQ_INSERT_TAIL(&intr_config_hook_list, hook, ich_links); if (next_to_notify == NULL) next_to_notify = hook; +#ifdef __rtems__ + run = intr_boot_done; +#endif /* __rtems__ */ mtx_unlock(&intr_config_hook_lock); #ifndef __rtems__ if (cold == 0) +#else /* __rtems__ */ + if (run) +#endif /* __rtems__ */ /* * XXX Call from a task since not all drivers expect * to be re-entered at the time a hook is established. */ /* XXX Sufficient for modules loaded after initial config??? */ run_interrupt_driven_config_hooks(); -#endif /* __rtems__ */ return (0); } diff --git a/testsuite/swi01/swi_test.c b/testsuite/swi01/swi_test.c index 4ec64cbb..630fa125 100644 --- a/testsuite/swi01/swi_test.c +++ b/testsuite/swi01/swi_test.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 2012 embedded brains GmbH. All rights reserved. + * Copyright (c) 2012, 2019 embedded brains GmbH. All rights reserved. * * embedded brains GmbH - * Obere Lagerstr. 30 + * Dornierstr. 4 * 82178 Puchheim * Germany * <rtems@embedded-brains.de> @@ -37,11 +37,11 @@ #include <unistd.h> #include <sys/types.h> -#include <sys/systm.h> - #include <sys/param.h> #include <sys/bus.h> #include <sys/interrupt.h> +#include <sys/kernel.h> +#include <sys/systm.h> #define SWI_TEST_THREAD_PRIO (0) @@ -194,6 +194,31 @@ void swi_test_error_has_allready_exclusive() assert(argument == HANDLER_NOT_VISITED); } +static void +ich_func(void *arg) +{ + int *invocations; + + invocations = arg; + ++(*invocations); +} + +static void +test_config_intrhook_establish(void) +{ + int invocations; + struct intr_config_hook hook = { + .ich_func = ich_func, + .ich_arg = &invocations + }; + + printf("== Test config_intrhook_establish().\n"); + + invocations = 0; + config_intrhook_establish(&hook); + assert(invocations == 1); +} + void swi_test(void) { swi_test_normal_handler(); @@ -204,5 +229,6 @@ void swi_test(void) swi_test_error_name_null(); swi_test_error_handler_null(); swi_test_error_has_allready_exclusive(); + test_config_intrhook_establish(); } |