1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Description:
8  *     Header file for FIP module used to parse the firmware
9  *     package.
10  */
11 
12 #ifndef MOD_FIP_H
13 #define MOD_FIP_H
14 
15 #include <fwk_attributes.h>
16 
17 #include <stddef.h>
18 #include <stdint.h>
19 
20 #define FIP_UUID_ENTRY_SIZE 16
21 #define FIP_TOC_HEADER_NAME UINT32_C(0xAA640001)
22 
23 /*!
24  * \addtogroup GroupModules Modules
25  * \{
26  */
27 
28 /*!
29  * \defgroup GroupFIP Firmware Image Package
30  *
31  * \brief Provides an API to access firmware image partitions.
32  *
33  * \details This module provides a table of descriptors that each describe a
34  *      block of firmware image entry in the underlying storage.
35  *
36  * \{
37  */
38 
39 /*!
40  * \defgroup GroupModuleFIPEntries FIP entries' identifiers.
41  * \{
42  */
43 
44 /*!
45  * \brief FIP TOC entry types.
46  */
47 enum mod_fip_toc_entry_type {
48     /*! NULL entry at end of fip image */
49     MOD_FIP_TOC_ENTRY_NULL,
50     /*! SCP Firmware BL2 */
51     MOD_FIP_TOC_ENTRY_SCP_BL2,
52     /*! TF-A runtime firmware BL31 */
53     MOD_FIP_TOC_ENTRY_TFA_BL31,
54     /*! Number of default enteries */
55     MOD_FIP_TOC_ENTRY_COUNT,
56 };
57 
58 /*
59  * Standard UUIDs as defined by TF-A.
60  */
61 
62 /*! NULL entry at end of fip image */
63 #define FIP_UUID_NULL \
64     (struct fip_uuid_desc) \
65     { \
66         .image_type = MOD_FIP_TOC_ENTRY_NULL, .uuid = { \
67             0x00, \
68             0x00, \
69             0x00, \
70             0x00, \
71             0x00, \
72             0x00, \
73             0x00, \
74             0x00, \
75             0x00, \
76             0x00, \
77             0x00, \
78             0x00, \
79             0x00, \
80             0x00, \
81             0x00, \
82             0x00 \
83         } \
84     }
85 
86 /*! SCP Firmware BL2 */
87 #define FIP_UUID_SCP_BL2 \
88     (struct fip_uuid_desc) \
89     { \
90         .image_type = MOD_FIP_TOC_ENTRY_SCP_BL2, .uuid = { \
91             0x97, \
92             0x66, \
93             0xfd, \
94             0x3d, \
95             0x89, \
96             0xbe, \
97             0xe8, \
98             0x49, \
99             0xae, \
100             0x5d, \
101             0x78, \
102             0xa1, \
103             0x40, \
104             0x60, \
105             0x82, \
106             0x13 \
107         } \
108     }
109 
110 /*! TF-A runtime firmware BL31 */
111 #define FIP_UUID_TFA_BL31 \
112     (struct fip_uuid_desc) \
113     { \
114         .image_type = MOD_FIP_TOC_ENTRY_TFA_BL31, .uuid = { \
115             0x47, \
116             0xd4, \
117             0x08, \
118             0x6d, \
119             0x4c, \
120             0xfe, \
121             0x98, \
122             0x46, \
123             0x9b, \
124             0x95, \
125             0x29, \
126             0x50, \
127             0xcb, \
128             0xbd, \
129             0x5a, \
130             0x00 \
131         } \
132     }
133 
134 /*!
135  * \}
136  */
137 
138 /*
139  * Firmware Image Package (FIP) layout.
140  *
141  * The FIP layout consists of a table of contents (ToC) followed by payload
142  * data.
143  *
144  * The ToC itself has a header followed by one or more table entries. The ToC
145  * is terminated by an end marker entry.
146  *
147  * All ToC entries describe some payload data that has been appended to the end
148  * of the binary package. With the information provided in the ToC entry the
149  * corresponding payload data can be retrieved.
150  *
151  *  +----------------+
152  *  | ToC Header     |
153  *  +----------------+
154  *  | ToC Entry 0    |
155  *  +----------------+
156  *  | ToC Entry 1    |
157  *  +----------------+
158  *  | ToC End Marker |
159  *  +----------------+
160  *  |                |
161  *  |     Data 0     |
162  *  |                |
163  *  +----------------+
164  *  |                |
165  *  |     Data 1     |
166  *  |                |
167  *  +----------------+
168  */
169 
170 /*!
171  * \brief An enum entry to UUID mapping structure
172  */
173 struct fip_uuid_desc {
174     /*! Enum entry for Image type */
175     enum mod_fip_toc_entry_type image_type;
176     /*! Entry UUID */
177     uint8_t uuid[FIP_UUID_ENTRY_SIZE];
178 };
179 
180 /*!
181  * \brief The ToC header fields structure
182  */
183 struct FWK_PACKED fip_toc_header {
184     /*! The name of the ToC */
185     uint32_t name;
186     /*! A non-zero number provided by the creation tool */
187     uint32_t serial_number;
188     /*! Flags associated with this data */
189     uint64_t flags;
190 };
191 
192 /*!
193  * \brief A ToC entry fields structure
194  */
195 struct FWK_PACKED fip_toc_entry {
196     /*! Entry UUID */
197     uint8_t uuid[FIP_UUID_ENTRY_SIZE];
198     /*! Offset address of payload data */
199     uint64_t offset_address;
200     /*! Size of the corresponding payload data in bytes */
201     uint64_t size;
202     /*! Flags associated with this entry */
203     uint64_t flags;
204 };
205 
206 /*!
207  * \brief Firmware Image Package (FIP) layout
208  */
209 struct FWK_PACKED fip_toc {
210     /*! ToC header */
211     struct fip_toc_header header;
212     /*! ToC table entries */
213     struct fip_toc_entry entry[];
214 };
215 
216 /*!
217  * \brief A memory-mapped FIP entry data (desribes a firmware image).
218  */
219 struct mod_fip_entry_data {
220     /*! Start of entry data */
221     void *base;
222     /*! Size */
223     size_t size;
224     /*! Flags */
225     uint64_t flags;
226 };
227 
228 /*!
229  * \brief APIs to access the FIP entry data.
230  */
231 struct mod_fip_api {
232     /*!
233      * \brief Retrieve a FIP entry's data.
234      *
235      * \param image_type FIP ToC entry type.
236      * \param[out] entry Updated if the type of entry requested is found.
237      * \param base Base address where FIP ToC resides.
238      * \param limit Maximum size of the media where FIP ToC resides.
239 
240      * \retval ::FWK_SUCCESS Entry found and \p entry updated.
241      * \retval ::FWK_E_INIT Underlying storage could not be parsed (during
242      *      init).
243      * \retval ::FWK_E_RANGE No entry of type \p type could be located.
244      * \retval ::FWK_E_DATA FIP ToC corrupted or otherwise not usable on this
245      *         platform.
246      */
247     int (*get_entry)(
248         enum mod_fip_toc_entry_type image_type,
249         struct mod_fip_entry_data *entry,
250         uintptr_t base,
251         size_t limit);
252 };
253 
254 /*!
255  * \brief fip module configuration.
256  */
257 struct mod_fip_module_config {
258     /*! Array of custom fip_uuid_desc entries */
259     struct fip_uuid_desc *custom_fip_uuid_desc_arr;
260     /*! Custom array element count */
261     size_t custom_uuid_desc_count;
262 };
263 
264 /*!
265  * \}
266  */
267 
268 /*!
269  * \}
270  */
271 
272 #endif /* MOD_FIP_H */
273