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