162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _LINUX_UML_INIT_H 362306a36Sopenharmony_ci#define _LINUX_UML_INIT_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci/* These macros are used to mark some functions or 662306a36Sopenharmony_ci * initialized data (doesn't apply to uninitialized data) 762306a36Sopenharmony_ci * as `initialization' functions. The kernel can take this 862306a36Sopenharmony_ci * as hint that the function is used only during the initialization 962306a36Sopenharmony_ci * phase and free up used memory resources after 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * Usage: 1262306a36Sopenharmony_ci * For functions: 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * You should add __init immediately before the function name, like: 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * static void __init initme(int x, int y) 1762306a36Sopenharmony_ci * { 1862306a36Sopenharmony_ci * extern int z; z = x * y; 1962306a36Sopenharmony_ci * } 2062306a36Sopenharmony_ci * 2162306a36Sopenharmony_ci * If the function has a prototype somewhere, you can also add 2262306a36Sopenharmony_ci * __init between closing brace of the prototype and semicolon: 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci * extern int initialize_foobar_device(int, int, int) __init; 2562306a36Sopenharmony_ci * 2662306a36Sopenharmony_ci * For initialized data: 2762306a36Sopenharmony_ci * You should insert __initdata between the variable name and equal 2862306a36Sopenharmony_ci * sign followed by value, e.g.: 2962306a36Sopenharmony_ci * 3062306a36Sopenharmony_ci * static int init_variable __initdata = 0; 3162306a36Sopenharmony_ci * static const char linux_logo[] __initconst = { 0x32, 0x36, ... }; 3262306a36Sopenharmony_ci * 3362306a36Sopenharmony_ci * Don't forget to initialize data not at file scope, i.e. within a function, 3462306a36Sopenharmony_ci * as gcc otherwise puts the data into the bss section and not into the init 3562306a36Sopenharmony_ci * section. 3662306a36Sopenharmony_ci * 3762306a36Sopenharmony_ci * Also note, that this data cannot be "const". 3862306a36Sopenharmony_ci */ 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#ifndef _LINUX_INIT_H 4162306a36Sopenharmony_citypedef int (*initcall_t)(void); 4262306a36Sopenharmony_citypedef void (*exitcall_t)(void); 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci#include <linux/compiler_types.h> 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci/* These are for everybody (although not all archs will actually 4762306a36Sopenharmony_ci discard it in modules) */ 4862306a36Sopenharmony_ci#define __init __section(".init.text") 4962306a36Sopenharmony_ci#define __initdata __section(".init.data") 5062306a36Sopenharmony_ci#define __exitdata __section(".exit.data") 5162306a36Sopenharmony_ci#define __exit_call __used __section(".exitcall.exit") 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci#ifdef MODULE 5462306a36Sopenharmony_ci#define __exit __section(".exit.text") 5562306a36Sopenharmony_ci#else 5662306a36Sopenharmony_ci#define __exit __used __section(".exit.text") 5762306a36Sopenharmony_ci#endif 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci#endif 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci#ifndef MODULE 6262306a36Sopenharmony_cistruct uml_param { 6362306a36Sopenharmony_ci const char *str; 6462306a36Sopenharmony_ci int (*setup_func)(char *, int *); 6562306a36Sopenharmony_ci}; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ciextern initcall_t __uml_postsetup_start, __uml_postsetup_end; 6862306a36Sopenharmony_ciextern const char *__uml_help_start, *__uml_help_end; 6962306a36Sopenharmony_ci#endif 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci#define __uml_exitcall(fn) \ 7262306a36Sopenharmony_ci static exitcall_t __uml_exitcall_##fn __uml_exit_call = fn 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ciextern struct uml_param __uml_setup_start, __uml_setup_end; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci#define __uml_postsetup(fn) \ 7762306a36Sopenharmony_ci static initcall_t __uml_postsetup_##fn __uml_postsetup_call = fn 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci#define __non_empty_string(dummyname,string) \ 8062306a36Sopenharmony_ci struct __uml_non_empty_string_struct_##dummyname \ 8162306a36Sopenharmony_ci { \ 8262306a36Sopenharmony_ci char _string[sizeof(string)-2]; \ 8362306a36Sopenharmony_ci } 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci#ifndef MODULE 8662306a36Sopenharmony_ci#define __uml_setup(str, fn, help...) \ 8762306a36Sopenharmony_ci __non_empty_string(fn ##_setup, str); \ 8862306a36Sopenharmony_ci __uml_help(fn, help); \ 8962306a36Sopenharmony_ci static char __uml_setup_str_##fn[] __initdata = str; \ 9062306a36Sopenharmony_ci static struct uml_param __uml_setup_##fn __uml_init_setup = { __uml_setup_str_##fn, fn } 9162306a36Sopenharmony_ci#else 9262306a36Sopenharmony_ci#define __uml_setup(str, fn, help...) \ 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci#endif 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci#define __uml_help(fn, help...) \ 9762306a36Sopenharmony_ci __non_empty_string(fn ##__help, help); \ 9862306a36Sopenharmony_ci static char __uml_help_str_##fn[] __initdata = help; \ 9962306a36Sopenharmony_ci static const char *__uml_help_##fn __uml_setup_help = __uml_help_str_##fn 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci/* 10262306a36Sopenharmony_ci * Mark functions and data as being only used at initialization 10362306a36Sopenharmony_ci * or exit time. 10462306a36Sopenharmony_ci */ 10562306a36Sopenharmony_ci#define __uml_init_setup __used __section(".uml.setup.init") 10662306a36Sopenharmony_ci#define __uml_setup_help __used __section(".uml.help.init") 10762306a36Sopenharmony_ci#define __uml_postsetup_call __used __section(".uml.postsetup.init") 10862306a36Sopenharmony_ci#define __uml_exit_call __used __section(".uml.exitcall.exit") 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci#ifdef __UM_HOST__ 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci#define __define_initcall(level,fn) \ 11362306a36Sopenharmony_ci static initcall_t __initcall_##fn __used \ 11462306a36Sopenharmony_ci __attribute__((__section__(".initcall" level ".init"))) = fn 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci/* Userspace initcalls shouldn't depend on anything in the kernel, so we'll 11762306a36Sopenharmony_ci * make them run first. 11862306a36Sopenharmony_ci */ 11962306a36Sopenharmony_ci#define __initcall(fn) __define_initcall("1", fn) 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci#define __exitcall(fn) static exitcall_t __exitcall_##fn __exit_call = fn 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci#define __init_call __used __section(".initcall.init") 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci#endif 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci#endif /* _LINUX_UML_INIT_H */ 128