xref: /freebsd/stand/common/modinfo.h (revision 5d1531d9d4e7d1b1b706ab23ac3f864416e87522)
1bca9c87bSWarner Losh /*-
2bca9c87bSWarner Losh  * Copyright (c) 2022, Netflix, Inc.
3bca9c87bSWarner Losh  *
4bca9c87bSWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
5bca9c87bSWarner Losh  */
6bca9c87bSWarner Losh #ifndef COMMON_MODINFO_H
7bca9c87bSWarner Losh #define COMMON_MODINFO_H
8bca9c87bSWarner Losh 
9bca9c87bSWarner Losh /*
10bca9c87bSWarner Losh  * Copy module-related data into the load area, where it can be
11bca9c87bSWarner Losh  * used as a directory for loaded modules.
12bca9c87bSWarner Losh  *
13bca9c87bSWarner Losh  * Module data is presented in a self-describing format.  Each datum
14bca9c87bSWarner Losh  * is preceded by a 32-bit identifier and a 32-bit size field.
15bca9c87bSWarner Losh  *
16bca9c87bSWarner Losh  * Currently, the following data are saved:
17bca9c87bSWarner Losh  *
18bca9c87bSWarner Losh  * MOD_NAME	(variable)		module name (string)
19bca9c87bSWarner Losh  * MOD_TYPE	(variable)		module type (string)
20bca9c87bSWarner Losh  * MOD_ARGS	(variable)		module parameters (string)
21bca9c87bSWarner Losh  * MOD_ADDR	sizeof(vm_offset_t)	module load address
22bca9c87bSWarner Losh  * MOD_SIZE	sizeof(size_t)		module size
23bca9c87bSWarner Losh  * MOD_METADATA	(variable)		type-specific metadata
24bca9c87bSWarner Losh  *
25bca9c87bSWarner Losh  * Clients are required to define a MOD_ALIGN(l) macro which rounds the passed
26bca9c87bSWarner Losh  * in length to the required alignment for the kernel being booted.
27bca9c87bSWarner Losh  */
28bca9c87bSWarner Losh 
29bca9c87bSWarner Losh #define COPY32(v, a, c) {			\
30bca9c87bSWarner Losh     uint32_t	x = (v);			\
31bca9c87bSWarner Losh     if (c)					\
32bca9c87bSWarner Losh         archsw.arch_copyin(&x, a, sizeof(x));	\
33bca9c87bSWarner Losh     a += sizeof(x);				\
34bca9c87bSWarner Losh }
35bca9c87bSWarner Losh 
36bca9c87bSWarner Losh #define MOD_STR(t, a, s, c) {			\
37bca9c87bSWarner Losh     COPY32(t, a, c);				\
38bca9c87bSWarner Losh     COPY32(strlen(s) + 1, a, c)			\
39bca9c87bSWarner Losh     if (c)					\
40bca9c87bSWarner Losh         archsw.arch_copyin(s, a, strlen(s) + 1);\
41bca9c87bSWarner Losh     a += MOD_ALIGN(strlen(s) + 1);		\
42bca9c87bSWarner Losh }
43bca9c87bSWarner Losh 
44bca9c87bSWarner Losh #define MOD_NAME(a, s, c)	MOD_STR(MODINFO_NAME, a, s, c)
45bca9c87bSWarner Losh #define MOD_TYPE(a, s, c)	MOD_STR(MODINFO_TYPE, a, s, c)
46bca9c87bSWarner Losh #define MOD_ARGS(a, s, c)	MOD_STR(MODINFO_ARGS, a, s, c)
47bca9c87bSWarner Losh 
48bca9c87bSWarner Losh #define MOD_VAR(t, a, s, c) {			\
49bca9c87bSWarner Losh     COPY32(t, a, c);				\
50bca9c87bSWarner Losh     COPY32(sizeof(s), a, c);			\
51bca9c87bSWarner Losh     if (c)					\
52bca9c87bSWarner Losh         archsw.arch_copyin(&s, a, sizeof(s));	\
53bca9c87bSWarner Losh     a += MOD_ALIGN(sizeof(s));			\
54bca9c87bSWarner Losh }
55bca9c87bSWarner Losh 
56bca9c87bSWarner Losh #define MOD_ADDR(a, s, c)	MOD_VAR(MODINFO_ADDR, a, s, c)
57bca9c87bSWarner Losh #define MOD_SIZE(a, s, c)	MOD_VAR(MODINFO_SIZE, a, s, c)
58bca9c87bSWarner Losh 
59bca9c87bSWarner Losh #define MOD_METADATA(a, mm, c) {		\
60bca9c87bSWarner Losh     COPY32(MODINFO_METADATA | mm->md_type, a, c);\
61bca9c87bSWarner Losh     COPY32(mm->md_size, a, c);			\
62bca9c87bSWarner Losh     if (c)					\
63bca9c87bSWarner Losh         archsw.arch_copyin(mm->md_data, a, mm->md_size);\
64bca9c87bSWarner Losh     a += MOD_ALIGN(mm->md_size);		\
65bca9c87bSWarner Losh }
66bca9c87bSWarner Losh 
67bca9c87bSWarner Losh #define MOD_END(a, c) {				\
68bca9c87bSWarner Losh     COPY32(MODINFO_END, a, c);			\
69bca9c87bSWarner Losh     COPY32(0, a, c);				\
70bca9c87bSWarner Losh }
71bca9c87bSWarner Losh 
72*5d1531d9SWarner Losh vm_offset_t md_copymodules(vm_offset_t addr, bool kern64);
73*5d1531d9SWarner Losh 
74bca9c87bSWarner Losh #endif /* COMMON_MODINFO_H */
75