1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * Copyright (c) 2014, Linaro Limited 4 */ 5 6 #ifndef INITCALL_H 7 #define INITCALL_H 8 9 #include <scattered_array.h> 10 #include <tee_api_types.h> 11 #include <trace.h> 12 13 struct initcall { 14 TEE_Result (*func)(void); 15 #if TRACE_LEVEL >= TRACE_DEBUG 16 int level; 17 const char *func_name; 18 #endif 19 }; 20 21 #if TRACE_LEVEL >= TRACE_DEBUG 22 #define __define_initcall(type, lvl, fn) \ 23 SCATTERED_ARRAY_DEFINE_PG_ITEM_ORDERED(type ## call, lvl, \ 24 struct initcall) = \ 25 { .func = (fn), .level = (lvl), .func_name = #fn, } 26 #else 27 #define __define_initcall(type, lvl, fn) \ 28 SCATTERED_ARRAY_DEFINE_PG_ITEM_ORDERED(type ## call, lvl, \ 29 struct initcall) = \ 30 { .func = (fn), } 31 #endif 32 33 #define preinitcall_begin \ 34 SCATTERED_ARRAY_BEGIN(preinitcall, struct initcall) 35 #define preinitcall_end SCATTERED_ARRAY_END(preinitcall, struct initcall) 36 37 #define initcall_begin SCATTERED_ARRAY_BEGIN(initcall, struct initcall) 38 #define initcall_end SCATTERED_ARRAY_END(initcall, struct initcall) 39 40 #define finalcall_begin SCATTERED_ARRAY_BEGIN(finalcall, struct initcall) 41 #define finalcall_end SCATTERED_ARRAY_END(finalcall, struct initcall) 42 43 /* 44 * The preinit_*(), *_init() and boot_final() macros are used to register 45 * callback functions to be called at different stages during 46 * initialization. 47 * 48 * Functions registered with preinit_*() are always called before functions 49 * registered with *_init(). 50 * 51 * Functions registered with boot_final() are called before exiting to 52 * normal world the first time. 53 * 54 * Without virtualization this happens in the order of the defines below. 55 * 56 * However, with virtualization things are a bit different. boot_final() 57 * functions are called first before exiting to normal world the first 58 * time. Functions registered with boot_final() can only operate on the 59 * nexus. preinit_*() functions are called early before the first yielding 60 * call into the partition, in the newly created partition. *_init() 61 * functions are called at the first yielding call. 62 * 63 * +-------------------------------+-----------------------------------+ 64 * | Without virtualization | With virtualization | 65 * +-------------------------------+-----------------------------------+ 66 * | At the end of boot_init_primary_late() just before the print: | 67 * | "Primary CPU switching to normal world boot" | 68 * +-------------------------------+-----------------------------------+ 69 * | 1. call_preinitcalls() | In the nexus | 70 * | 2. call_initcalls() +-----------------------------------+ 71 * | 3. call_finalcalls() | 1. call_finalcalls() | 72 * +-------------------------------+-----------------------------------+ 73 * | "Primary CPU switching to normal world boot" is printed | 74 * +-------------------------------+-----------------------------------+ 75 * | A guest is created and | 76 * | virt_guest_created() is called. | 77 * | After the partition has been | 78 * | created and activated. | 79 * +-----------------------------------+ 80 * | 2. call_preinitcalls() | 81 * +-----------------------------------+ 82 * | When the partition is receiving | 83 * | the first yielding call | 84 * | virt_on_stdcall() is called. | 85 * +-----------------------------------+ 86 * | 3. call_initcalls() | 87 * +-----------------------------------+ 88 */ 89 90 #define preinit_early(fn) __define_initcall(preinit, 1, fn) 91 #define preinit(fn) __define_initcall(preinit, 2, fn) 92 #define preinit_late(fn) __define_initcall(preinit, 3, fn) 93 94 #define early_init(fn) __define_initcall(init, 1, fn) 95 #define early_init_late(fn) __define_initcall(init, 2, fn) 96 #define service_init(fn) __define_initcall(init, 3, fn) 97 #define service_init_late(fn) __define_initcall(init, 4, fn) 98 #define driver_init(fn) __define_initcall(init, 5, fn) 99 #define driver_init_late(fn) __define_initcall(init, 6, fn) 100 #define release_init_resource(fn) __define_initcall(init, 7, fn) 101 102 #define boot_final(fn) __define_initcall(final, 1, fn) 103 104 void call_preinitcalls(void); 105 void call_initcalls(void); 106 void call_finalcalls(void); 107 108 #endif 109