1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2020 Intel Corporation. All rights reserved.
4  *
5  * Author: Karol Trzcinski <karolx.trzcinski@linux.intel.com>
6  */
7 
8 /*
9  * Parts of this file are copied to ext_manifest.h in Linux kernel tree
10  * and to the rimage tree. This duplication is OK because it is part of
11  * a versioned ABI.
12  */
13 
14 /*
15  * Extended manifest is a place to store metadata about firmware, known during
16  * compilation time - for example firmware version or used compiler.
17  * Given information are read on host side before firmware startup.
18  * This part of output binary is not signed.
19  *
20  * To add new content to ext_man, in firmware code define struct which starts
21  * with ext_man_elem_head followed by usage dependent content and place whole
22  * struct in "fw_metadata" section. Moreover kernel code should be modified to
23  * properly read new packet.
24  *
25  * Extended manifest is designed to be extensible. In header there is a field
26  * which describe header length, so after appending some data to header then it
27  * can be easily skipped by device with older version of this header.
28  * Unknown ext_man elements should be just skipped by host,
29  * to be backward compatible. Field `ext_man_elem_header.elem_size` should be
30  * used in such a situation.
31  */
32 
33 #ifndef __KERNEL_EXT_MANIFEST_H__
34 #define __KERNEL_EXT_MANIFEST_H__
35 
36 #include <ipc/info.h>
37 #include <sof/compiler_attributes.h>
38 #include <stdint.h>
39 
40 /* Top-level headers shared with rimage */
41 
42 #ifndef __packed
43 #define __packed __attribute__((packed))
44 #endif
45 
46 /* In ASCII `XMan` */
47 #define EXT_MAN_MAGIC_NUMBER	0x6e614d58
48 
49 /* Build u32 number in format MMmmmppp */
50 #define EXT_MAN_BUILD_VERSION(MAJOR, MINOR, PATH) ( \
51 	((uint32_t)(MAJOR) << 24) | \
52 	((uint32_t)(MINOR) << 12) | \
53 	(uint32_t)(PATH))
54 
55 /* check extended manifest version consistency */
56 #define EXT_MAN_VERSION_INCOMPATIBLE(host_ver, cli_ver) ( \
57 	((host_ver) & GENMASK(31, 24)) != \
58 	((cli_ver) & GENMASK(31, 24)))
59 
60 /* used extended manifest header version */
61 #define EXT_MAN_VERSION		EXT_MAN_BUILD_VERSION(1, 0, 0)
62 
63 /* struct size alignment for ext_man elements */
64 #define EXT_MAN_ALIGN 16
65 
66 /* extended manifest header, deleting any field breaks backward compatibility */
67 struct ext_man_header {
68 	uint32_t magic;		/**< identification number, */
69 				/**< EXT_MAN_MAGIC_NUMBER */
70 	uint32_t full_size;	/**< [bytes] full size of ext_man, */
71 				/**< (header + content + padding) */
72 	uint32_t header_size;	/**< [bytes] makes header extensionable, */
73 				/**< after append new field to ext_man header */
74 				/**< then backward compatible won't be lost */
75 	uint32_t header_version; /**< value of EXT_MAN_VERSION */
76 				/**< not related with following content */
77 
78 	/* just after this header should be list of ext_man_elem_* elements */
79 } __packed;
80 
81 /* Now define extended manifest elements */
82 
83 /* extended manifest element header */
84 struct ext_man_elem_header {
85 	uint32_t type;		/**< EXT_MAN_ELEM_* */
86 	uint32_t elem_size;	/**< in bytes, including header size */
87 
88 	/* just after this header should be type dependent content */
89 } __packed;
90 
91 /* End of the top-level headers shared with rimage */
92 
93 /* Extended manifest elements identificators */
94 enum ext_man_elem_type {
95 	EXT_MAN_ELEM_FW_VERSION		= 0,
96 	EXT_MAN_ELEM_WINDOW		= SOF_IPC_EXT_WINDOW,
97 	EXT_MAN_ELEM_CC_VERSION		= SOF_IPC_EXT_CC_INFO,
98 	EXT_MAN_ELEM_PROBE_INFO		= SOF_IPC_EXT_PROBE_INFO,
99 	EXT_MAN_ELEM_DBG_ABI		= SOF_IPC_EXT_USER_ABI_INFO, /**< ABI3.17 */
100 	EXT_MAN_ELEM_CONFIG_DATA	= 5,    /**< ABI3.17 */
101 	EXT_MAN_ELEM_PLATFORM_CONFIG_DATA = 6,  /**< ABI3.17 */
102 };
103 
104 /* EXT_MAN_ELEM_CONFIG_DATA elements identificators */
105 enum config_elem_type {
106 	EXT_MAN_CONFIG_IPC_MSG_SIZE	= 1,
107 	EXT_MAN_CONFIG_MEMORY_USAGE_SCAN = 2, /**< ABI3.18 */
108 	EXT_MAN_CONFIG_LAST_ELEM,	/**< keep it at the end of enum list */
109 };
110 
111 struct config_elem {
112 	uint32_t token;
113 	uint32_t value;
114 } __attribute__((packed, aligned(4)));
115 
116 /* FW version */
117 struct ext_man_fw_version {
118 	struct ext_man_elem_header hdr;
119 	/* use sof_ipc struct because of code re-use */
120 	struct sof_ipc_fw_version version;
121 	uint32_t flags;
122 } __attribute__((packed, aligned(4)));
123 
124 /* windows info */
125 struct ext_man_windows {
126 	struct ext_man_elem_header hdr;
127 	/* use sof_ipc struct because of code re-use */
128 	struct sof_ipc_window window;
129 } __attribute__((packed, aligned(4)));
130 
131 /* Used C compiler description */
132 struct ext_man_cc_version {
133 	struct ext_man_elem_header hdr;
134 	/* use sof_ipc struct because of code re-use */
135 	struct sof_ipc_cc_version cc_version;
136 } __attribute__((packed, aligned(4)));
137 
138 struct ext_man_probe_support {
139 	struct ext_man_elem_header hdr;
140 	/* use sof_ipc struct because of code re-use */
141 	struct sof_ipc_probe_support probe;
142 } __attribute__((packed, aligned(4)));
143 
144 struct ext_man_dbg_abi {
145 	struct ext_man_elem_header hdr;
146 	/* use sof_ipc struct because of code re-use */
147 	struct sof_ipc_user_abi_version dbg_abi;
148 } __attribute__((packed, aligned(4)));
149 
150 /** EXT_MAN_ELEM_CONFIG_DATA elements (ABI3.17) */
151 struct ext_man_config_data {
152 	struct ext_man_elem_header hdr;
153 
154 	struct config_elem elems[];
155 } __attribute__((packed, aligned(4)));
156 
157 #endif /* __KERNEL_EXT_MANIFEST_H__ */
158