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