11bb92983SJerome Forissier /* SPDX-License-Identifier: BSD-2-Clause */ 203c21dc9SSY Chiu /* 303c21dc9SSY Chiu * Copyright (c) 2014, Linaro Limited 403c21dc9SSY Chiu */ 503c21dc9SSY Chiu 603c21dc9SSY Chiu #ifndef INITCALL_H 703c21dc9SSY Chiu #define INITCALL_H 803c21dc9SSY Chiu 99e592338SJens Wiklander #include <scattered_array.h> 1003c21dc9SSY Chiu #include <tee_api_types.h> 119f0a24daSJens Wiklander #include <trace.h> 1203c21dc9SSY Chiu 139f0a24daSJens Wiklander struct initcall { 149f0a24daSJens Wiklander TEE_Result (*func)(void); 159f0a24daSJens Wiklander #if TRACE_LEVEL >= TRACE_DEBUG 169f0a24daSJens Wiklander int level; 179f0a24daSJens Wiklander const char *func_name; 189f0a24daSJens Wiklander #endif 199f0a24daSJens Wiklander }; 2003c21dc9SSY Chiu 219f0a24daSJens Wiklander #if TRACE_LEVEL >= TRACE_DEBUG 22e3172f9dSJens Wiklander #define __define_initcall(type, lvl, fn) \ 23e3172f9dSJens Wiklander SCATTERED_ARRAY_DEFINE_PG_ITEM_ORDERED(type ## call, lvl, \ 249f0a24daSJens Wiklander struct initcall) = \ 259f0a24daSJens Wiklander { .func = (fn), .level = (lvl), .func_name = #fn, } 269f0a24daSJens Wiklander #else 27e3172f9dSJens Wiklander #define __define_initcall(type, lvl, fn) \ 28e3172f9dSJens Wiklander SCATTERED_ARRAY_DEFINE_PG_ITEM_ORDERED(type ## call, lvl, \ 299f0a24daSJens Wiklander struct initcall) = \ 309f0a24daSJens Wiklander { .func = (fn), } 319f0a24daSJens Wiklander #endif 3203c21dc9SSY Chiu 33*bd59a6adSJens Wiklander #define preinitcall_begin \ 34*bd59a6adSJens Wiklander SCATTERED_ARRAY_BEGIN(preinitcall, struct initcall) 35*bd59a6adSJens Wiklander #define preinitcall_end SCATTERED_ARRAY_END(preinitcall, struct initcall) 36*bd59a6adSJens Wiklander 379f0a24daSJens Wiklander #define initcall_begin SCATTERED_ARRAY_BEGIN(initcall, struct initcall) 389f0a24daSJens Wiklander #define initcall_end SCATTERED_ARRAY_END(initcall, struct initcall) 399e592338SJens Wiklander 40e3172f9dSJens Wiklander #define finalcall_begin SCATTERED_ARRAY_BEGIN(finalcall, struct initcall) 41e3172f9dSJens Wiklander #define finalcall_end SCATTERED_ARRAY_END(finalcall, struct initcall) 42e3172f9dSJens Wiklander 43*bd59a6adSJens Wiklander /* 44*bd59a6adSJens Wiklander * The preinit_*(), *_init() and boot_final() macros are used to register 45*bd59a6adSJens Wiklander * callback functions to be called at different stages during 46*bd59a6adSJens Wiklander * initialization. 47*bd59a6adSJens Wiklander * 48*bd59a6adSJens Wiklander * Functions registered with preinit_*() are always called before functions 49*bd59a6adSJens Wiklander * registered with *_init(). 50*bd59a6adSJens Wiklander * 51*bd59a6adSJens Wiklander * Functions registered with boot_final() are called before exiting to 52*bd59a6adSJens Wiklander * normal world the first time. 53*bd59a6adSJens Wiklander * 54*bd59a6adSJens Wiklander * Without virtualization this happens in the order of the defines below. 55*bd59a6adSJens Wiklander * 56*bd59a6adSJens Wiklander * However, with virtualization things are a bit different. boot_final() 57*bd59a6adSJens Wiklander * functions are called first before exiting to normal world the first 58*bd59a6adSJens Wiklander * time. Functions registered with boot_final() can only operate on the 59*bd59a6adSJens Wiklander * nexus. preinit_*() functions are called early before the first yielding 60*bd59a6adSJens Wiklander * call into the partition, in the newly created partition. *_init() 61*bd59a6adSJens Wiklander * functions are called at the first yielding call. 62*bd59a6adSJens Wiklander * 63*bd59a6adSJens Wiklander * +-------------------------------+-----------------------------------+ 64*bd59a6adSJens Wiklander * | Without virtualization | With virtualization | 65*bd59a6adSJens Wiklander * +-------------------------------+-----------------------------------+ 66*bd59a6adSJens Wiklander * | At the end of boot_init_primary_late() just before the print: | 67*bd59a6adSJens Wiklander * | "Primary CPU switching to normal world boot" | 68*bd59a6adSJens Wiklander * +-------------------------------+-----------------------------------+ 69*bd59a6adSJens Wiklander * | 1. call_preinitcalls() | In the nexus | 70*bd59a6adSJens Wiklander * | 2. call_initcalls() +-----------------------------------+ 71*bd59a6adSJens Wiklander * | 3. call_finalcalls() | 1. call_finalcalls() | 72*bd59a6adSJens Wiklander * +-------------------------------+-----------------------------------+ 73*bd59a6adSJens Wiklander * | "Primary CPU switching to normal world boot" is printed | 74*bd59a6adSJens Wiklander * +-------------------------------+-----------------------------------+ 75*bd59a6adSJens Wiklander * | A guest is created and | 76*bd59a6adSJens Wiklander * | virt_guest_created() is called. | 77*bd59a6adSJens Wiklander * | After the partition has been | 78*bd59a6adSJens Wiklander * | created and activated. | 79*bd59a6adSJens Wiklander * +-----------------------------------+ 80*bd59a6adSJens Wiklander * | 2. call_preinitcalls() | 81*bd59a6adSJens Wiklander * +-----------------------------------+ 82*bd59a6adSJens Wiklander * | When the partition is receiving | 83*bd59a6adSJens Wiklander * | the first yielding call | 84*bd59a6adSJens Wiklander * | virt_on_stdcall() is called. | 85*bd59a6adSJens Wiklander * +-----------------------------------+ 86*bd59a6adSJens Wiklander * | 3. call_initcalls() | 87*bd59a6adSJens Wiklander * +-----------------------------------+ 88*bd59a6adSJens Wiklander */ 89*bd59a6adSJens Wiklander 90*bd59a6adSJens Wiklander #define preinit_early(fn) __define_initcall(preinit, 1, fn) 91*bd59a6adSJens Wiklander #define preinit(fn) __define_initcall(preinit, 2, fn) 92*bd59a6adSJens Wiklander #define preinit_late(fn) __define_initcall(preinit, 3, fn) 93*bd59a6adSJens Wiklander 94e3172f9dSJens Wiklander #define early_init(fn) __define_initcall(init, 1, fn) 95e3172f9dSJens Wiklander #define early_init_late(fn) __define_initcall(init, 2, fn) 96e3172f9dSJens Wiklander #define service_init(fn) __define_initcall(init, 3, fn) 97e3172f9dSJens Wiklander #define service_init_late(fn) __define_initcall(init, 4, fn) 98e3172f9dSJens Wiklander #define driver_init(fn) __define_initcall(init, 5, fn) 99e3172f9dSJens Wiklander #define driver_init_late(fn) __define_initcall(init, 6, fn) 100e3172f9dSJens Wiklander 101e3172f9dSJens Wiklander #define boot_final(fn) __define_initcall(final, 1, fn) 1029e592338SJens Wiklander 103*bd59a6adSJens Wiklander void call_preinitcalls(void); 104c5c56024SJens Wiklander void call_initcalls(void); 105e3172f9dSJens Wiklander void call_finalcalls(void); 10603c21dc9SSY Chiu 10703c21dc9SSY Chiu #endif 108