From aedff4f6e887b8da7e359a28f3c0393a2112087d Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 25 Jul 2019 10:20:19 +0200 Subject: CONFIG_INTRHOOK(9): Call handlers after boot This enables adding drivers on demand which use this service after initialization. --- freebsd/sys/kern/subr_autoconf.c | 16 +++++++++++++++- 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 * @@ -37,11 +37,11 @@ #include #include -#include - #include #include #include +#include +#include #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(); } -- cgit v1.2.3