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