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
23 using namespace elftosb;
24
IVTDataSource()25 IVTDataSource::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
getData(unsigned offset,unsigned maxBytes,uint8_t * buffer)36 unsigned 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
getLength()63 unsigned 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 //!
hasNaturalLocation()70 bool IVTDataSource::hasNaturalLocation()
71 {
72 return m_isSelfSet;
73 }
74
75 //!
getBaseAddress()76 uint32_t IVTDataSource::getBaseAddress()
77 {
78 return m_ivt.self;
79 }
80
setFieldByName(const std::string & name,uint32_t value)81 bool 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