/src/barebox/include/image-metadata.h
Line | Count | Source |
1 | | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | | #ifndef __INCLUDE_IMAGE_METADTA_H |
3 | | #define __INCLUDE_IMAGE_METADTA_H |
4 | | |
5 | | /* |
6 | | * barebox Image MetaData (IMD) |
7 | | * |
8 | | * IMD is a mechanism to store metadata in barebox images. With IMD |
9 | | * it's possible to extract the release, the build timestamp and the |
10 | | * board type from a barebox image. |
11 | | * |
12 | | * Since there is no fixed place in the image suitable for all SoC image |
13 | | * types the metadata can be stored anywhere in the image and is found |
14 | | * by iterating over the image. The metadata starts with a start header |
15 | | * and ends with an end header. All tags in between carry the payload. |
16 | | * |
17 | | * Make sure source files containing IMD data are compiled with lwl-y so |
18 | | * that the tags end up in the PBL if one exists and in the regular image |
19 | | * without PBL. |
20 | | * |
21 | | * The following types exist: |
22 | | */ |
23 | 0 | #define IMD_TYPE_START 0x640c0001 |
24 | | #define IMD_TYPE_RELEASE 0x640c8002 /* The barebox release aka UTS_RELEASE */ |
25 | | #define IMD_TYPE_BUILD 0x640c8003 /* build number and timestamp (UTS_VERSION) */ |
26 | | #define IMD_TYPE_MODEL 0x640c8004 /* The board name this image is for */ |
27 | | #define IMD_TYPE_OF_COMPATIBLE 0x640c8005 /* the device tree compatible string */ |
28 | 0 | #define IMD_TYPE_PARAMETER 0x640c8006 /* A generic parameter. Use key=value as data */ |
29 | | #define IMD_TYPE_BUILDSYSTEM 0x640c8007 /* The buildsystem version barebox was built with */ |
30 | 0 | #define IMD_TYPE_CRC32 0x640c1007 /* the checksum of the barebox images */ |
31 | 0 | #define IMD_TYPE_END 0x640c7fff |
32 | 0 | #define IMD_TYPE_INVALID 0xffffffff |
33 | | |
34 | 0 | #define IMD_CRC32_FLAG_TAG_VALID (1 << 0) |
35 | | |
36 | | /* |
37 | | * The IMD header. All data is stored in little endian format in the image. |
38 | | * The next header starts at the next 4 byte boundary after the data. |
39 | | */ |
40 | | struct imd_header { |
41 | | uint32_t type; /* One of IMD_TYPE_* above */ |
42 | | uint32_t datalength; /* Length of the data (exluding the header) */ |
43 | | }; |
44 | | |
45 | | /* |
46 | | * A IMD string. Set bit 15 of the IMD_TYPE to indicate the data is printable |
47 | | * as string. |
48 | | */ |
49 | | struct imd_entry_string { |
50 | | struct imd_header header; |
51 | | char data[]; |
52 | | }; |
53 | | |
54 | | static inline int imd_is_string(uint32_t type) |
55 | 0 | { |
56 | 0 | return (type & 0x8000) ? 1 : 0; |
57 | 0 | } Unexecuted instantiation: imd.c:imd_is_string Unexecuted instantiation: imd-barebox.c:imd_is_string |
58 | | |
59 | | /* |
60 | | * A IMD int. |
61 | | */ |
62 | | struct imd_entry_crc32 { |
63 | | struct imd_header header; |
64 | | uint32_t data; |
65 | | uint32_t flags; |
66 | | }; |
67 | | |
68 | | static inline int imd_is_crc32(uint32_t type) |
69 | 0 | { |
70 | 0 | return type == IMD_TYPE_CRC32; |
71 | 0 | } Unexecuted instantiation: imd.c:imd_is_crc32 Unexecuted instantiation: imd-barebox.c:imd_is_crc32 |
72 | | |
73 | | static inline int imd_crc32_is_valid(uint32_t flags) |
74 | 0 | { |
75 | 0 | return (flags & IMD_CRC32_FLAG_TAG_VALID) ? 1 : 0; |
76 | 0 | } Unexecuted instantiation: imd.c:imd_crc32_is_valid Unexecuted instantiation: imd-barebox.c:imd_crc32_is_valid |
77 | | |
78 | 0 | static inline int imd_type_valid(uint32_t type) { |
79 | 0 | return (type & 0xffff0000) == 0x640c0000; |
80 | 0 | } Unexecuted instantiation: imd.c:imd_type_valid Unexecuted instantiation: imd-barebox.c:imd_type_valid |
81 | | |
82 | | const struct imd_header *imd_next(const struct imd_header *imd); |
83 | | |
84 | | #define imd_for_each(start, imd) \ |
85 | 0 | for (imd = imd_next(start); imd_read_type(imd) != IMD_TYPE_END; imd = imd_next(imd)) |
86 | | |
87 | | static inline uint32_t imd_read_le32(const void *_ptr) |
88 | 0 | { |
89 | 0 | const uint8_t *ptr = _ptr; |
90 | |
|
91 | 0 | return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24); |
92 | 0 | } Unexecuted instantiation: imd.c:imd_read_le32 Unexecuted instantiation: imd-barebox.c:imd_read_le32 |
93 | | |
94 | | static inline uint32_t imd_read_type(const struct imd_header *imd) |
95 | 0 | { |
96 | 0 | return imd_read_le32(&imd->type); |
97 | 0 | } Unexecuted instantiation: imd.c:imd_read_type Unexecuted instantiation: imd-barebox.c:imd_read_type |
98 | | |
99 | | static inline uint32_t imd_read_length(const struct imd_header *imd) |
100 | 0 | { |
101 | 0 | return imd_read_le32(&imd->datalength); |
102 | 0 | } Unexecuted instantiation: imd.c:imd_read_length Unexecuted instantiation: imd-barebox.c:imd_read_length |
103 | | |
104 | | static inline uint32_t imd_read_flags(const struct imd_entry_crc32 *imd) |
105 | 0 | { |
106 | 0 | return imd_read_le32(&imd->flags); |
107 | 0 | } Unexecuted instantiation: imd.c:imd_read_flags Unexecuted instantiation: imd-barebox.c:imd_read_flags |
108 | | |
109 | | const struct imd_header *imd_find_type(const struct imd_header *imd, |
110 | | uint32_t type); |
111 | | |
112 | | const struct imd_header *imd_get(const void *buf, int size); |
113 | | const char *imd_string_data(const struct imd_header *imd, int index); |
114 | | const uint32_t *imd_uint32_data(const struct imd_header *imd); |
115 | | uint32_t *imd_uint32_flags(const struct imd_header *imd); |
116 | | const char *imd_type_to_name(uint32_t type); |
117 | | char *imd_concat_strings(const struct imd_header *imd); |
118 | | const char *imd_get_param(const struct imd_header *imd, const char *name); |
119 | | |
120 | | extern int imd_command_verbose; |
121 | | int imd_command_setenv(const char *variable_name, const char *value); |
122 | | int imd_command(int argc, char *argv[]); |
123 | | int imd_verify_crc32(void *buf, size_t size); |
124 | | |
125 | | #ifdef __BAREBOX__ |
126 | | |
127 | | #include <linux/stringify.h> |
128 | | #include <linux/compiler_types.h> |
129 | | |
130 | | #define __BAREBOX_IMD_SECTION(_section) \ |
131 | | __ll_elem(_section) __attribute__((aligned(4))) |
132 | | |
133 | | #define BAREBOX_IMD_TAG_STRING(_name, _type, _string, _keep_if_unused) \ |
134 | | const struct imd_entry_string __barebox_imd_##_name \ |
135 | | __BAREBOX_IMD_SECTION(.barebox_imd_ ## _keep_if_unused ## _ ## _name) = { \ |
136 | | .header.type = cpu_to_le32(_type), \ |
137 | | .header.datalength = cpu_to_le32(sizeof(_string)), \ |
138 | | .data = _string, \ |
139 | | } |
140 | | |
141 | | #define BAREBOX_IMD_CRC(_name, _crc, _keep_if_unused) \ |
142 | | const struct imd_entry_crc32 __barebox_imd_##__name \ |
143 | | __BAREBOX_IMD_SECTION(.barebox_imd_ ## _keep_if_unused ## _ ## _name) = { \ |
144 | | .header.type = cpu_to_le32(IMD_TYPE_CRC32), \ |
145 | | .header.datalength = cpu_to_le32(sizeof(uint32_t) * 2), \ |
146 | | .data = _crc, \ |
147 | | } |
148 | | |
149 | | #ifdef CONFIG_IMD |
150 | | void imd_used(const void *); |
151 | | #else |
152 | | static inline void imd_used(const void *unused) |
153 | | { |
154 | | } |
155 | | #endif |
156 | | |
157 | | #define IMD_USED(_name) \ |
158 | | imd_used(&__barebox_imd_##_name) |
159 | | |
160 | | __attribute__((deprecated("IMD entries are now always referenced if DT itself is"))) |
161 | | static inline void IMD_USED_OF(void) |
162 | 0 | {}Unexecuted instantiation: imd.c:IMD_USED_OF Unexecuted instantiation: imd-barebox.c:IMD_USED_OF |
163 | | |
164 | | #define IMD_USED_OF(_name) IMD_USED_OF() |
165 | | |
166 | | #endif /* __BAREBOX__ */ |
167 | | |
168 | | #endif /* __INCLUDE_IMAGE_METADTA_H */ |