CONFIG_INTRHOOK(9): Call handlers after boot

This enables adding drivers on demand which use this service after
initialization.
This commit is contained in:
Sebastian Huber 2019-07-25 10:20:19 +02:00
parent f052790a24
commit 989e2dd76e
2 changed files with 45 additions and 5 deletions

View File

@ -63,6 +63,9 @@ static TAILQ_HEAD(, intr_config_hook) intr_config_hook_list =
static struct intr_config_hook *next_to_notify; static struct intr_config_hook *next_to_notify;
static struct mtx intr_config_hook_lock; static struct mtx intr_config_hook_lock;
MTX_SYSINIT(intr_config_hook, &intr_config_hook_lock, "intr config", MTX_DEF); MTX_SYSINIT(intr_config_hook, &intr_config_hook_lock, "intr config", MTX_DEF);
#ifdef __rtems__
static bool intr_boot_done;
#endif /* __rtems__ */
/* ARGSUSED */ /* ARGSUSED */
static void run_interrupt_driven_config_hooks(void); 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); mtx_lock(&intr_config_hook_lock);
} }
} }
#ifdef __rtems__
intr_boot_done = true;
#endif /* __rtems__ */
mtx_unlock(&intr_config_hook_lock); mtx_unlock(&intr_config_hook_lock);
TSUNWAIT("config hooks"); TSUNWAIT("config hooks");
} }
@ -190,6 +196,9 @@ int
config_intrhook_establish(struct intr_config_hook *hook) config_intrhook_establish(struct intr_config_hook *hook)
{ {
struct intr_config_hook *hook_entry; struct intr_config_hook *hook_entry;
#ifdef __rtems__
bool run;
#endif /* __rtems__ */
TSHOLD("config hooks"); TSHOLD("config hooks");
mtx_lock(&intr_config_hook_lock); 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); TAILQ_INSERT_TAIL(&intr_config_hook_list, hook, ich_links);
if (next_to_notify == NULL) if (next_to_notify == NULL)
next_to_notify = hook; next_to_notify = hook;
#ifdef __rtems__
run = intr_boot_done;
#endif /* __rtems__ */
mtx_unlock(&intr_config_hook_lock); mtx_unlock(&intr_config_hook_lock);
#ifndef __rtems__ #ifndef __rtems__
if (cold == 0) if (cold == 0)
#else /* __rtems__ */
if (run)
#endif /* __rtems__ */
/* /*
* XXX Call from a task since not all drivers expect * XXX Call from a task since not all drivers expect
* to be re-entered at the time a hook is established. * to be re-entered at the time a hook is established.
*/ */
/* XXX Sufficient for modules loaded after initial config??? */ /* XXX Sufficient for modules loaded after initial config??? */
run_interrupt_driven_config_hooks(); run_interrupt_driven_config_hooks();
#endif /* __rtems__ */
return (0); return (0);
} }

View File

@ -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 * embedded brains GmbH
* Obere Lagerstr. 30 * Dornierstr. 4
* 82178 Puchheim * 82178 Puchheim
* Germany * Germany
* <rtems@embedded-brains.de> * <rtems@embedded-brains.de>
@ -37,11 +37,11 @@
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/systm.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/bus.h> #include <sys/bus.h>
#include <sys/interrupt.h> #include <sys/interrupt.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#define SWI_TEST_THREAD_PRIO (0) #define SWI_TEST_THREAD_PRIO (0)
@ -194,6 +194,31 @@ void swi_test_error_has_allready_exclusive()
assert(argument == HANDLER_NOT_VISITED); 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) void swi_test(void)
{ {
swi_test_normal_handler(); swi_test_normal_handler();
@ -204,5 +229,6 @@ void swi_test(void)
swi_test_error_name_null(); swi_test_error_name_null();
swi_test_error_handler_null(); swi_test_error_handler_null();
swi_test_error_has_allready_exclusive(); swi_test_error_has_allready_exclusive();
test_config_intrhook_establish();
} }