xref: /netbsd-src/external/bsd/elftosb/dist/common/IVTDataSource.cpp (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 
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