]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - tools/elftosb/common/IVTDataSource.cpp
merged tx6dl-devel into denx master branch
[karo-tx-uboot.git] / tools / elftosb / common / IVTDataSource.cpp
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
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
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
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 //!
70 bool IVTDataSource::hasNaturalLocation()
71 {
72     return m_isSelfSet;
73 }
74
75 //!
76 uint32_t IVTDataSource::getBaseAddress()
77 {
78     return m_ivt.self;
79 }
80
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