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 33bd59a6adSJens Wiklander #define preinitcall_begin \ 34bd59a6adSJens Wiklander SCATTERED_ARRAY_BEGIN(preinitcall, struct initcall) 35bd59a6adSJens Wiklander #define preinitcall_end SCATTERED_ARRAY_END(preinitcall, struct initcall) 36bd59a6adSJens 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 43bd59a6adSJens Wiklander /* 44bd59a6adSJens Wiklander * The preinit_*(), *_init() and boot_final() macros are used to register 45bd59a6adSJens Wiklander * callback functions to be called at different stages during 46bd59a6adSJens Wiklander * initialization. 47bd59a6adSJens Wiklander * 48bd59a6adSJens Wiklander * Functions registered with preinit_*() are always called before functions 49bd59a6adSJens Wiklander * registered with *_init(). 50bd59a6adSJens Wiklander * 51bd59a6adSJens Wiklander * Functions registered with boot_final() are called before exiting to 52bd59a6adSJens Wiklander * normal world the first time. 53bd59a6adSJens Wiklander * 54bd59a6adSJens Wiklander * Without virtualization this happens in the order of the defines below. 55bd59a6adSJens Wiklander * 56bd59a6adSJens Wiklander * However, with virtualization things are a bit different. boot_final() 57bd59a6adSJens Wiklander * functions are called first before exiting to normal world the first 58bd59a6adSJens Wiklander * time. Functions registered with boot_final() can only operate on the 59bd59a6adSJens Wiklander * nexus. preinit_*() functions are called early before the first yielding 60bd59a6adSJens Wiklander * call into the partition, in the newly created partition. *_init() 61bd59a6adSJens Wiklander * functions are called at the first yielding call. 62bd59a6adSJens Wiklander * 63bd59a6adSJens Wiklander * +-------------------------------+-----------------------------------+ 64bd59a6adSJens Wiklander * | Without virtualization | With virtualization | 65bd59a6adSJens Wiklander * +-------------------------------+-----------------------------------+ 66bd59a6adSJens Wiklander * | At the end of boot_init_primary_late() just before the print: | 67bd59a6adSJens Wiklander * | "Primary CPU switching to normal world boot" | 68bd59a6adSJens Wiklander * +-------------------------------+-----------------------------------+ 69bd59a6adSJens Wiklander * | 1. call_preinitcalls() | In the nexus | 70bd59a6adSJens Wiklander * | 2. call_initcalls() +-----------------------------------+ 71bd59a6adSJens Wiklander * | 3. call_finalcalls() | 1. call_finalcalls() | 72bd59a6adSJens Wiklander * +-------------------------------+-----------------------------------+ 73bd59a6adSJens Wiklander * | "Primary CPU switching to normal world boot" is printed | 74bd59a6adSJens Wiklander * +-------------------------------+-----------------------------------+ 75bd59a6adSJens Wiklander * | A guest is created and | 76bd59a6adSJens Wiklander * | virt_guest_created() is called. | 77bd59a6adSJens Wiklander * | After the partition has been | 78bd59a6adSJens Wiklander * | created and activated. | 79bd59a6adSJens Wiklander * +-----------------------------------+ 80bd59a6adSJens Wiklander * | 2. call_preinitcalls() | 81bd59a6adSJens Wiklander * +-----------------------------------+ 82bd59a6adSJens Wiklander * | When the partition is receiving | 83bd59a6adSJens Wiklander * | the first yielding call | 84bd59a6adSJens Wiklander * | virt_on_stdcall() is called. | 85bd59a6adSJens Wiklander * +-----------------------------------+ 86bd59a6adSJens Wiklander * | 3. call_initcalls() | 87bd59a6adSJens Wiklander * +-----------------------------------+ 88bd59a6adSJens Wiklander */ 89bd59a6adSJens Wiklander 90bd59a6adSJens Wiklander #define preinit_early(fn) __define_initcall(preinit, 1, fn) 91bd59a6adSJens Wiklander #define preinit(fn) __define_initcall(preinit, 2, fn) 92bd59a6adSJens Wiklander #define preinit_late(fn) __define_initcall(preinit, 3, fn) 93bd59a6adSJens 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) 100*94d4f61dSEtienne Carriere #define release_init_resource(fn) __define_initcall(init, 7, fn) 101e3172f9dSJens Wiklander 102e3172f9dSJens Wiklander #define boot_final(fn) __define_initcall(final, 1, fn) 1039e592338SJens Wiklander 104bd59a6adSJens Wiklander void call_preinitcalls(void); 105c5c56024SJens Wiklander void call_initcalls(void); 106e3172f9dSJens Wiklander void call_finalcalls(void); 10703c21dc9SSY Chiu 10803c21dc9SSY Chiu #endif 109