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 early_initcall_begin \ 38 SCATTERED_ARRAY_BEGIN(early_initcall, struct initcall) 39 #define early_initcall_end \ 40 SCATTERED_ARRAY_END(early_initcall, struct initcall) 41 42 #define service_initcall_begin \ 43 SCATTERED_ARRAY_BEGIN(service_initcall, struct initcall) 44 #define service_initcall_end \ 45 SCATTERED_ARRAY_END(service_initcall, struct initcall) 46 47 #define driver_initcall_begin \ 48 SCATTERED_ARRAY_BEGIN(driver_initcall, struct initcall) 49 #define driver_initcall_end \ 50 SCATTERED_ARRAY_END(driver_initcall, struct initcall) 51 52 #define finalcall_begin SCATTERED_ARRAY_BEGIN(finalcall, struct initcall) 53 #define finalcall_end SCATTERED_ARRAY_END(finalcall, struct initcall) 54 55 /* 56 * The preinit_*(), *_init() and boot_final() macros are used to register 57 * callback functions to be called at different stages during 58 * initialization. 59 * 60 * Functions registered with preinit_*() are always called before functions 61 * registered with *_init(). 62 * 63 * Functions registered with boot_final() are called before exiting to 64 * normal world the first time. 65 * 66 * Without virtualization this happens in the order of the defines below. 67 * 68 * However, with virtualization things are a bit different. boot_final() 69 * functions are called first before exiting to normal world the first 70 * time. Functions registered with boot_final() can only operate on the 71 * nexus. preinit_*() functions are called early before the first yielding 72 * call into the partition, in the newly created partition. *_init() 73 * functions are called at the first yielding call. 74 * 75 * +-------------------------------+-----------------------------------+ 76 * | Without virtualization | With virtualization | 77 * +-------------------------------+-----------------------------------+ 78 * | At the end of boot_init_primary_late() just before the print: | 79 * | "Primary CPU switching to normal world boot" | 80 * +-------------------------------+-----------------------------------+ 81 * | 1. call_preinitcalls() | In the nexus, final calls | 82 * | 2. call_initcalls() +-----------------------------------+ 83 * | 3. call_finalcalls() | 1. boot_final() / nex_*init*() | 84 * +-------------------------------+-----------------------------------+ 85 * | "Primary CPU switching to normal world boot" is printed | 86 * +-------------------------------+-----------------------------------+ 87 * | A guest is created and | 88 * | virt_guest_created() is called. | 89 * | After the partition has been | 90 * | created and activated. | 91 * +-----------------------------------+ 92 * | 2. call_preinitcalls() | 93 * +-----------------------------------+ 94 * | When the partition is receiving | 95 * | the first yielding call | 96 * | virt_on_stdcall() is called. | 97 * +-----------------------------------+ 98 * | 3. call_initcalls() | 99 * +-----------------------------------+ 100 */ 101 102 #define preinit_early(fn) __define_initcall(preinit, 1, fn) 103 #define preinit(fn) __define_initcall(preinit, 2, fn) 104 #define preinit_late(fn) __define_initcall(preinit, 3, fn) 105 106 #define early_init(fn) __define_initcall(early_init, 1, fn) 107 #define early_init_late(fn) __define_initcall(early_init, 2, fn) 108 #define service_init_crypto(fn) __define_initcall(service_init, 1, fn) 109 #define service_init(fn) __define_initcall(service_init, 2, fn) 110 #define service_init_late(fn) __define_initcall(service_init, 3, fn) 111 #define driver_init(fn) __define_initcall(driver_init, 1, fn) 112 #define driver_init_late(fn) __define_initcall(driver_init, 2, fn) 113 #define release_init_resource(fn) __define_initcall(driver_init, 3, fn) 114 115 #define boot_final(fn) __define_initcall(final, 1, fn) 116 117 /* 118 * These nex_* init-calls are provided for drivers and services that reside 119 * in the nexus in case of virtualization. The init-calls are performed 120 * before exiting to the non-secure world at the end of boot 121 * initialization. In case of virtualization the init-calls are based on 122 * final calls, while otherwise are the same as the non-nex counterpart. 123 */ 124 #ifdef CFG_NS_VIRTUALIZATION 125 #define nex_early_init(fn) boot_final(fn) 126 #define nex_early_init_late(fn) __define_initcall(final, 2, fn) 127 #define nex_service_init(fn) __define_initcall(final, 3, fn) 128 #define nex_service_init_late(fn) __define_initcall(final, 4, fn) 129 #define nex_driver_init(fn) __define_initcall(final, 5, fn) 130 #define nex_driver_init_late(fn) __define_initcall(final, 6, fn) 131 #define nex_release_init_resource(fn) __define_initcall(final, 7, fn) 132 #else 133 #define nex_early_init(fn) early_init(fn) 134 #define nex_early_init_late(fn) early_init_late(fn) 135 #define nex_service_init(fn) service_init(fn) 136 #define nex_service_init_late(fn) service_init_late(fn) 137 #define nex_driver_init(fn) driver_init(fn) 138 #define nex_driver_init_late(fn) driver_init_late(fn) 139 #define nex_release_init_resource(fn) release_init_resource(fn) 140 #endif 141 142 void call_preinitcalls(void); 143 void call_early_initcalls(void); 144 void call_service_initcalls(void); 145 void call_driver_initcalls(void); 146 void call_initcalls(void); 147 void call_finalcalls(void); 148 149 #endif 150