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 16#include "IVTDataSource.h" 17#include "DataTarget.h" 18#include "EndianUtilities.h" 19#include <algorithm> 20#include <stdlib.h> 21#include <string.h> 22 23using namespace elftosb; 24 25IVTDataSource::IVTDataSource() 26: DataSource(), 27 DataSource::Segment((DataSource&)*this), 28 m_isSelfSet(false) 29{ 30 // Init the IVT structure. 31 memset(&m_ivt, 0, sizeof(m_ivt)); 32 hab_hdr_t hdr = IVT_HDR(sizeof(m_ivt), HAB_VERSION); 33 m_ivt.hdr = hdr; 34} 35 36unsigned IVTDataSource::getData(unsigned offset, unsigned maxBytes, uint8_t * buffer) 37{ 38 // Bail if the offset is out of range. 39 if (offset >= sizeof(m_ivt)) 40 { 41 return 0; 42 } 43 44 // If we have an associated target, and the IVT self pointer is not set, then 45 // fill in the self pointer from the target address. 46 if (m_target && !m_isSelfSet) 47 { 48 m_ivt.self = ENDIAN_HOST_TO_LITTLE_U32(m_target->getBeginAddress()); 49 } 50 51 // Truncate max bytes at the end of the IVT. 52 maxBytes = std::min<unsigned>(maxBytes, sizeof(m_ivt) - offset); 53 54 // Copy into output buffer. 55 if (maxBytes) 56 { 57 memcpy(buffer, (uint8_t *)&m_ivt + offset, maxBytes); 58 } 59 60 return maxBytes; 61} 62 63unsigned IVTDataSource::getLength() 64{ 65 return sizeof(m_ivt); 66} 67 68//! The IVT has a natural location if its self pointer was explicitly specified. 69//! 70bool IVTDataSource::hasNaturalLocation() 71{ 72 return m_isSelfSet; 73} 74 75//! 76uint32_t IVTDataSource::getBaseAddress() 77{ 78 return m_ivt.self; 79} 80 81bool IVTDataSource::setFieldByName(const std::string & name, uint32_t value) 82{ 83 if (name == "entry") 84 { 85 m_ivt.entry = ENDIAN_HOST_TO_LITTLE_U32(value); 86 } 87 else if (name == "dcd") 88 { 89 m_ivt.dcd = ENDIAN_HOST_TO_LITTLE_U32(value); 90 } 91 else if (name == "boot_data") 92 { 93 m_ivt.boot_data = ENDIAN_HOST_TO_LITTLE_U32(value); 94 } 95 else if (name == "self") 96 { 97 m_ivt.self = ENDIAN_HOST_TO_LITTLE_U32(value); 98 m_isSelfSet = true; 99 } 100 else if (name == "csf") 101 { 102 m_ivt.csf = ENDIAN_HOST_TO_LITTLE_U32(value); 103 } 104 else 105 { 106 // Unrecognized field name. 107 return false; 108 } 109 110 return true; 111} 112 113 114