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