]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - tools/elftosb/common/IVTDataSource.h
merged tx6dl-devel into denx master branch
[karo-tx-uboot.git] / tools / elftosb / common / IVTDataSource.h
1 /*
2  * File:        DataSource.h
3  *
4  * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5  *
6  * Freescale Semiconductor, Inc.
7  * Proprietary & Confidential
8  *
9  * This source code and the algorithms implemented therein constitute
10  * confidential information and may comprise trade secrets of Freescale Semiconductor, Inc.
11  * or its associates, and any use thereof is subject to the terms and
12  * conditions of the Confidential Disclosure Agreement pursual to which this
13  * source code was originally received.
14  */
15 #if !defined(_IVTDataSource_h_)
16 #define _IVTDataSource_h_
17
18 #include "DataSource.h"
19
20 /** Header field components
21  * @ingroup hdr
22  */
23 typedef struct hab_hdr {
24     uint8_t tag;              /**< Tag field */
25     uint8_t len[2];           /**< Length field in bytes (big-endian) */
26     uint8_t par;              /**< Parameters field */
27 } hab_hdr_t;
28
29 /** Image entry function prototype
30  *  @ingroup rvt
31  *
32  * This typedef serves as the return type for hab_rvt.authenticate_image().  It
33  * specifies a void-void function pointer, but can be cast to another function
34  * pointer type if required.
35  */
36 typedef void (*hab_image_entry_f)(void);
37
38 /** @ref ivt structure
39  * @ingroup ivt
40  *
41  * @par Format
42  *
43  * An @ref ivt consists of a @ref hdr followed by a list of addresses as
44  * described further below.
45  *
46  * @warning The @a entry address may not be NULL.
47  *
48  * @warning On an IC not configured as #HAB_CFG_CLOSED, the
49  * @a csf address may be NULL.  If it is not NULL, the @ref csf will be
50  * processed, but any failures should be non-fatal.
51  *
52  * @warning On an IC configured as #HAB_CFG_CLOSED, the @a
53  * csf address may not be NULL, and @ref csf failures are typically fatal.
54  *
55  * @remark The Boot Data located using the @a boot_data field is interpreted
56  * by the HAB caller in a boot-mode specific manner.  This may be used by the
57  * boot ROM as to determine the load address and boot device configuration for
58  * images loaded from block devices (see @ref ref_rug for details).
59  *
60  * @remark All addresses given in the IVT, including the Boot Data (if
61  * present) are those for the final load location. 
62  *
63  * @anchor ila
64  *
65  * @par Initial load addresses
66  *
67  * The @a self field is used to calculate addresses in boot modes where an
68  * initial portion of the image is loaded to an initial location.  In such
69  * cases, the IVT, Boot Data (if present) and DCD (if present) are used in
70  * configuring the IC and loading the full image to its final location.  Only
71  * the IVT, Boot Data (if present) and DCD (if present) are required to be
72  * within the initial image portion.
73  *
74  * The method for calculating an initial load address for the DCD is
75  * illustrated in the following C fragment.  Similar calculations apply to
76  * other fields.
77  *
78 @verbatim
79         hab_ivt_t* ivt_initial = <initial IVT load address>;
80         const void* dcd_initial = ivt_initial->dcd;
81         if (ivt_initial->dcd != NULL)
82             dcd_initial = (const uint8_t*)ivt_initial 
83                           + (ivt_initial->dcd - ivt_initial->self)
84 @endverbatim
85
86  * \note The void* types in this structure have been changed to uint32_t so
87  *      that this code will work correctly when compiled on a 64-bit host.
88  *      Otherwise the structure would come out incorrect.
89  */
90 struct hab_ivt {
91     /** @ref hdr with tag #HAB_TAG_IVT, length and HAB version fields
92      *  (see @ref data)
93      */
94     hab_hdr_t hdr;
95     /** Absolute address of the first instruction to execute from the
96      *  image
97      */
98     /*hab_image_entry_f*/ uint32_t entry;
99     /** Reserved in this version of HAB: should be NULL. */
100     /*const void*/ uint32_t reserved1;
101     /** Absolute address of the image DCD: may be NULL. */
102     /*const void*/ uint32_t dcd;
103     /** Absolute address of the Boot Data: may be NULL, but not interpreted
104      *  any further by HAB
105      */
106     /*const void*/ uint32_t boot_data;
107     /** Absolute address of the IVT.*/
108     /*const void*/ uint32_t self;
109     /** Absolute address of the image CSF.*/
110     /*const void*/ uint32_t csf;
111     /** Reserved in this version of HAB: should be zero. */
112     uint32_t reserved2;
113 };
114
115 /** @ref ivt type
116  * @ingroup ivt
117  */
118 typedef struct hab_ivt hab_ivt_t;
119
120 /*
121  *    Helper macros
122  */
123 #define HAB_CMD_UNS     0xff
124
125 #define DEFAULT_IMG_KEY_IDX     2
126
127 #define GEN_MASK(width)                         \
128     ((1UL << (width)) - 1)
129
130 #define GEN_FIELD(f, width, shift)              \
131     (((f) & GEN_MASK(width)) << (shift))
132
133 #define PACK_UINT32(a, b, c, d)                 \
134     ( (((a) & 0xFF) << 24)                      \
135       |(((b) & 0xFF) << 16)                     \
136       |(((c) & 0xFF) << 8)                      \
137       |(((d) & 0xFF)) )
138
139 #define EXPAND_UINT32(w)                                                \
140     (uint8_t)((w)>>24), (uint8_t)((w)>>16), (uint8_t)((w)>>8), (uint8_t)(w)
141
142 #define HDR(tag, bytes, par)                                            \
143     (uint8_t)(tag), (uint8_t)((bytes)>>8), (uint8_t)(bytes), (uint8_t)(par)
144
145 #define HAB_VER(maj, min)                                       \
146     (GEN_FIELD((maj), HAB_VER_MAJ_WIDTH, HAB_VER_MAJ_SHIFT)     \
147      | GEN_FIELD((min), HAB_VER_MIN_WIDTH, HAB_VER_MIN_SHIFT))
148
149 /*
150  *    CSF header
151  */
152
153 #define CSF_HDR(bytes, HABVER)                  \
154     HDR(HAB_TAG_CSF, (bytes), HABVER)
155     
156     
157 /*
158  *    DCD  header
159  */
160
161 #define DCD_HDR(bytes, HABVER)                  \
162     HDR(HAB_TAG_DCD, (bytes), HABVER)
163
164 /*
165  *   IVT  header (goes in the struct's hab_hdr_t field, not a byte array)
166  */
167 #define IVT_HDR(bytes, HABVER)                  \
168     {HAB_TAG_IVT, {(uint8_t)((bytes)>>8), (uint8_t)(bytes)}, HABVER}
169
170 /** @name External data structure tags
171  * @anchor dat_tag
172  *
173  * Tag values 0x00 .. 0xef are reserved for HAB.  Values 0xf0 .. 0xff
174  * are available for custom use.
175  */
176 /*@{*/
177 #define HAB_TAG_IVT  0xd1       /**< Image Vector Table */
178 #define HAB_TAG_DCD  0xd2       /**< Device Configuration Data */
179 #define HAB_TAG_CSF  0xd4       /**< Command Sequence File */
180 #define HAB_TAG_CRT  0xd7       /**< Certificate */
181 #define HAB_TAG_SIG  0xd8       /**< Signature */
182 #define HAB_TAG_EVT  0xdb       /**< Event */
183 #define HAB_TAG_RVT  0xdd       /**< ROM Vector Table */
184 /* Values b0 ... cf reserved for CSF commands.  Values e0 ... ef reserved for
185  * key types.
186  *
187  * Available values: 03, 05, 06, 09, 0a, 0c, 0f, 11, 12, 14, 17, 18, 1b, 1d,
188  * 1e, 21, 22, 24, 27, 28, 2b, 2d, 2e, 30, 33, 35, 36, 39, 3a, 3c, 3f, 41, 42,
189  * 44, 47, 48, 4b, 4d, 4e, 50, 53, 55, 56, 59, 5a, 5c, 5f, 60, 63, 65, 66, 69,
190  * 6a, 6c, 6f, 71, 72, 74, 77, 78, 7b, 7d, 7e, 81, 82, 84, 87, 88, 8b, 8d, 8e,
191  * 90, 93, 95, 96, 99, 9a, 9c, 9f, a0, a3, a5, a6, a9, aa, ac, af, b1, b2, b4,
192  * b7, b8, bb, bd, be
193  *
194  * Custom values: f0, f3, f5, f6, f9, fa, fc, ff
195  */
196 /*@}*/
197
198 /** @name HAB version */
199 /*@{*/
200 #define HAB_MAJOR_VERSION  4    /**< Major version of this HAB release */
201 #define HAB_MINOR_VERSION  0    /**< Minor version of this HAB release */
202 #define HAB_VER_MAJ_WIDTH 4     /**< Major version field width  */
203 #define HAB_VER_MAJ_SHIFT 4     /**< Major version field offset  */
204 #define HAB_VER_MIN_WIDTH 4     /**< Minor version field width  */
205 #define HAB_VER_MIN_SHIFT 0     /**< Minor version field offset  */
206 /** Full version of this HAB release @hideinitializer */
207 #define HAB_VERSION HAB_VER(HAB_MAJOR_VERSION, HAB_MINOR_VERSION) 
208 /** Base version for this HAB release @hideinitializer */
209 #define HAB_BASE_VERSION HAB_VER(HAB_MAJOR_VERSION, 0) 
210
211 /*@}*/
212
213 namespace elftosb {
214
215 /*!
216  * \brief Data source for an IVT structure used by HAB4.
217  *
218  * This data source represents an IVT structure used by HAB4. Fields of the IVT can be set
219  * by name, making it easy to interface with a parser. And it has some intelligence regarding
220  * the IVT's self pointer. Before the data is copied out by the getData() method, the self field
221  * will be filled in automatically if it has not already been set and there is an associated
222  * data target object. This lets the IVT pick up its own address from the location where it is
223  * being loaded. Alternatively, if the self pointer is filled in explicitly, then the data
224  * source will have a natural location equal to the self pointer.
225  *
226  * This data source acts as its own segment.
227  */
228 class IVTDataSource : public DataSource, public DataSource::Segment
229 {
230 public:
231     //! \brief Default constructor.
232     IVTDataSource();
233     
234         //! \brief There is only one segment.
235         virtual unsigned getSegmentCount() { return 1; }
236         
237         //! \brief Returns this object, as it is its own segment.
238         virtual DataSource::Segment * getSegmentAt(unsigned index) { return this; }
239
240     //! \name Segment methods
241     //@{
242     
243     //! \brief Copy out some or all of the IVT structure.
244     //!
245     virtual unsigned getData(unsigned offset, unsigned maxBytes, uint8_t * buffer);
246     
247     //! \brief Gets the length of the segment's data.
248     virtual unsigned getLength();
249     
250     //! \brief Returns whether the segment has an associated address.
251     virtual bool hasNaturalLocation();
252     
253     //! \brief Returns the address associated with the segment.
254     virtual uint32_t getBaseAddress();
255     
256     //@}
257     
258     //! \name IVT access
259     //@{
260     
261     //! \brief Set one of the IVT's fields by providing its name.
262     //!
263     //! Acceptable field names are:
264     //! - entry
265     //! - dcd
266     //! - boot_data
267     //! - self
268     //! - csf
269     //!
270     //! As long as the \a name parameter specifies one of these fields, the return value
271     //! will be true. If \a name contains any other value, then false will be returned and
272     //! the IVT left unmodified.
273     //!
274     //! Once the \a self field has been set to any value, the data source will have a
275     //! natural location. This works even if the \a self address is 0.
276     //!
277     //! \param name The name of the field to set. Field names are case sensitive, just like in
278     //!     the C language.
279     //! \param value The value to which the field will be set.
280     //! \retval true The field was set successfully.
281     //! \retval false There is no field with the provided name.
282     bool setFieldByName(const std::string & name, uint32_t value);
283     
284     //! \brief Returns a reference to the IVT structure.
285     hab_ivt_t & getIVT() { return m_ivt; }
286     
287     //@}
288
289 protected:
290     hab_ivt_t m_ivt;  //!< The IVT structure.
291     bool m_isSelfSet; //!< True if the IVT self pointer was explicitly set.
292 };
293
294 } // elftosb
295
296 #endif // _IVTDataSource_h_