Anthony Liguori | 0bfe3ca | 2009-05-14 19:29:53 +0100 | [diff] [blame] | 1 | /* |
| 2 | * QEMU Module Infrastructure |
| 3 | * |
| 4 | * Copyright IBM, Corp. 2009 |
| 5 | * |
| 6 | * Authors: |
| 7 | * Anthony Liguori <aliguori@us.ibm.com> |
| 8 | * |
| 9 | * This work is licensed under the terms of the GNU GPL, version 2. See |
| 10 | * the COPYING file in the top-level directory. |
| 11 | * |
Paolo Bonzini | 6b620ca | 2012-01-13 17:44:23 +0100 | [diff] [blame] | 12 | * Contributions after 2012-01-13 are licensed under the terms of the |
| 13 | * GNU GPL, version 2 or (at your option) any later version. |
Anthony Liguori | 0bfe3ca | 2009-05-14 19:29:53 +0100 | [diff] [blame] | 14 | */ |
| 15 | |
| 16 | #include "qemu-common.h" |
Blue Swirl | 72cf2d4 | 2009-09-12 07:36:22 +0000 | [diff] [blame] | 17 | #include "qemu-queue.h" |
Anthony Liguori | 0bfe3ca | 2009-05-14 19:29:53 +0100 | [diff] [blame] | 18 | #include "module.h" |
| 19 | |
| 20 | typedef struct ModuleEntry |
| 21 | { |
| 22 | module_init_type type; |
| 23 | void (*init)(void); |
Blue Swirl | 72cf2d4 | 2009-09-12 07:36:22 +0000 | [diff] [blame] | 24 | QTAILQ_ENTRY(ModuleEntry) node; |
Anthony Liguori | 0bfe3ca | 2009-05-14 19:29:53 +0100 | [diff] [blame] | 25 | } ModuleEntry; |
| 26 | |
Blue Swirl | 72cf2d4 | 2009-09-12 07:36:22 +0000 | [diff] [blame] | 27 | typedef QTAILQ_HEAD(, ModuleEntry) ModuleTypeList; |
Anthony Liguori | f789743 | 2009-05-14 17:57:31 -0500 | [diff] [blame] | 28 | |
| 29 | static ModuleTypeList init_type_list[MODULE_INIT_MAX]; |
| 30 | |
| 31 | static void init_types(void) |
Anthony Liguori | 0bfe3ca | 2009-05-14 19:29:53 +0100 | [diff] [blame] | 32 | { |
Anthony Liguori | f789743 | 2009-05-14 17:57:31 -0500 | [diff] [blame] | 33 | static int inited; |
| 34 | int i; |
Anthony Liguori | 0bfe3ca | 2009-05-14 19:29:53 +0100 | [diff] [blame] | 35 | |
Anthony Liguori | f789743 | 2009-05-14 17:57:31 -0500 | [diff] [blame] | 36 | if (inited) { |
| 37 | return; |
Anthony Liguori | 0bfe3ca | 2009-05-14 19:29:53 +0100 | [diff] [blame] | 38 | } |
| 39 | |
Anthony Liguori | f789743 | 2009-05-14 17:57:31 -0500 | [diff] [blame] | 40 | for (i = 0; i < MODULE_INIT_MAX; i++) { |
Blue Swirl | 72cf2d4 | 2009-09-12 07:36:22 +0000 | [diff] [blame] | 41 | QTAILQ_INIT(&init_type_list[i]); |
Anthony Liguori | 0bfe3ca | 2009-05-14 19:29:53 +0100 | [diff] [blame] | 42 | } |
| 43 | |
Anthony Liguori | f789743 | 2009-05-14 17:57:31 -0500 | [diff] [blame] | 44 | inited = 1; |
| 45 | } |
| 46 | |
| 47 | |
| 48 | static ModuleTypeList *find_type(module_init_type type) |
| 49 | { |
| 50 | ModuleTypeList *l; |
| 51 | |
| 52 | init_types(); |
| 53 | |
| 54 | l = &init_type_list[type]; |
| 55 | |
| 56 | return l; |
Anthony Liguori | 0bfe3ca | 2009-05-14 19:29:53 +0100 | [diff] [blame] | 57 | } |
| 58 | |
| 59 | void register_module_init(void (*fn)(void), module_init_type type) |
| 60 | { |
| 61 | ModuleEntry *e; |
| 62 | ModuleTypeList *l; |
| 63 | |
Anthony Liguori | 7267c09 | 2011-08-20 22:09:37 -0500 | [diff] [blame] | 64 | e = g_malloc0(sizeof(*e)); |
Anthony Liguori | 0bfe3ca | 2009-05-14 19:29:53 +0100 | [diff] [blame] | 65 | e->init = fn; |
| 66 | |
Anthony Liguori | f789743 | 2009-05-14 17:57:31 -0500 | [diff] [blame] | 67 | l = find_type(type); |
Anthony Liguori | 0bfe3ca | 2009-05-14 19:29:53 +0100 | [diff] [blame] | 68 | |
Blue Swirl | 72cf2d4 | 2009-09-12 07:36:22 +0000 | [diff] [blame] | 69 | QTAILQ_INSERT_TAIL(l, e, node); |
Anthony Liguori | 0bfe3ca | 2009-05-14 19:29:53 +0100 | [diff] [blame] | 70 | } |
| 71 | |
| 72 | void module_call_init(module_init_type type) |
| 73 | { |
| 74 | ModuleTypeList *l; |
| 75 | ModuleEntry *e; |
| 76 | |
Anthony Liguori | f789743 | 2009-05-14 17:57:31 -0500 | [diff] [blame] | 77 | l = find_type(type); |
Anthony Liguori | 0bfe3ca | 2009-05-14 19:29:53 +0100 | [diff] [blame] | 78 | |
Blue Swirl | 72cf2d4 | 2009-09-12 07:36:22 +0000 | [diff] [blame] | 79 | QTAILQ_FOREACH(e, l, node) { |
Anthony Liguori | 0bfe3ca | 2009-05-14 19:29:53 +0100 | [diff] [blame] | 80 | e->init(); |
| 81 | } |
| 82 | } |