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