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