1 #ifndef PLATFORM_LIBS_H 2 #define PLATFORM_LIBS_H 3 4 /** 5 * Copyright (c) 2019, The Linux Foundation. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are 9 * met: 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above 13 * copyright notice, this list of conditions and the following 14 * disclaimer in the documentation and/or other materials provided 15 * with the distribution. 16 * * Neither the name of The Linux Foundation nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 21 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 27 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 29 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 30 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 Platfrom Library Loader 35 ----------------------- 36 37 proj/platform_libs is a library to help manage interdependencies between 38 other libraries. 39 40 41 to use you will need to add 42 43 incs = { 'proj/platform_libs' } 44 45 in source of the library implementation define the entry point 46 47 #include "platform_libs.h" 48 PL_DEFINE(svfs, svfs_init, svfs_deinit); 49 50 Platfrom Library List 51 --------------------- 52 53 This list contains top level libraries to be initialized at boot. To make 54 sure that this library is loaded you would need to call PLRegister or 55 PLRegisterDefault in your scons build command. 56 57 58 Handling Interdependencies and Order 59 ------------------------------------ 60 61 To make sure that library A is loaded before library B, library B's 62 constructor and destructor should initialize and cleanup libraryB. 63 64 #include "platform_libs.h" 65 66 PL_DEP(libraryB) 67 void libraryA_deinit(void) { 68 PL_DEINIT(libraryB); 69 } 70 71 int libraryA_init(void) { 72 int nErr = 0; 73 // my init code 74 VERIFY(0 == PL_INIT(libraryB)); 75 bail: 76 if(nErr) { libraryA_deinit() } 77 return nErr; 78 } 79 80 81 libraryB does not need to appear in the platform library list. 82 */ 83 84 #include <stdint.h> 85 86 struct platform_lib { 87 const char* name; 88 uint32_t uRefs; 89 int nErr; 90 int (*init)(void); 91 void (*deinit)(void); 92 }; 93 94 /** 95 * use this macro to pull in external dependencies 96 */ 97 #ifdef __cplusplus 98 #define PL_DEP(name)\ 99 extern "C" {\ 100 extern struct platform_lib* _pl_##name(void); \ 101 } 102 #else 103 #define PL_DEP(name)\ 104 extern struct platform_lib* _pl_##name(void); 105 #endif /* __cplusplus */ 106 107 /** 108 * should be declared in source in the library 109 * if constructor fails, destructor is not called 110 */ 111 #ifdef __cplusplus 112 #define PL_DEFINE(name, init, deinit) \ 113 extern "C" {\ 114 struct platform_lib* _pl_##name(void) {\ 115 static struct platform_lib _gpl_##name = { #name, 0, -1, init, deinit };\ 116 return &_gpl_##name;\ 117 }\ 118 } 119 #else 120 #define PL_DEFINE(name, init, deinit) \ 121 struct platform_lib* _pl_##name(void) {\ 122 static struct platform_lib _gpl_##name = { #name, 0, -1, init, deinit };\ 123 return &_gpl_##name;\ 124 } 125 #endif /* __cplusplus */ 126 127 /** 128 * should be added to platform_libs_list.c pl_list table 129 * for all top level modules 130 */ 131 #define PL_ENTRY(name) _pl_##name 132 133 /** 134 * should be called within a constructor to ensure that a 135 * dependency has been initialized. so if foo depends on bar 136 * 137 * #include "bar.h" 138 * int foo_init() { 139 * return PL_INIT(bar); 140 * } 141 */ 142 #define PL_INIT(name) pl_lib_init(PL_ENTRY(name)) 143 144 /** 145 * should be called within a destructor to ensure that a 146 * dependency has been cleaned up 147 */ 148 #define PL_DEINIT(name) pl_lib_deinit(PL_ENTRY(name)) 149 150 #ifdef __cplusplus 151 extern "C" { 152 #endif /* __cplusplus */ 153 154 /** 155 * initalize the static list of library constructors and destructors 156 * should be called from main() 157 * 158 * see platform_libs_list.h to add high level libraries 159 * 160 */ 161 int pl_init(void); 162 163 /** 164 * calls all the destructors. 165 */ 166 void pl_deinit(void); 167 168 /** 169 * initialize a single library. called via PL_INIT 170 */ 171 int pl_lib_init(struct platform_lib* (*pl)(void)); 172 173 /** 174 * deinitialize a single library called via PL_DEINIT 175 */ 176 void pl_lib_deinit(struct platform_lib* (*pl)(void)); 177 178 #ifdef __cplusplus 179 } 180 #endif 181 182 #endif //PLATFORM_LIBS 183