summaryrefslogtreecommitdiffstats
path: root/common/Operation.h
blob: 2b184e37cb37b79bbeb9827c06b098763de39f31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*
 * File:	Operation.h
 *
 * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
 * See included license file for license details.
 */
#if !defined(_Operation_h_)
#define _Operation_h_

#include "stdafx.h"
#include <vector>
#include "DataSource.h"
#include "DataTarget.h"
#include "smart_ptr.h"

namespace elftosb
{

/*!
 * \brief Abstract base class for all boot operations.
 */
class Operation
{
public:
	Operation() {}
	virtual ~Operation() {}
};

/*!
 * \brief Load data into memory operation.
 */
class LoadOperation : public Operation
{
public:
	LoadOperation() : Operation(), m_source(), m_target() {}
	
	void setSource(DataSource * source);
	inline DataSource * getSource() { return m_source; }
	
	void setTarget(DataTarget * target);
	inline DataTarget * getTarget() { return m_target; }
	
	inline void setDCDLoad(bool isDCD) { m_isDCDLoad = isDCD; }
	inline bool isDCDLoad() const { return m_isDCDLoad; }
	
protected:
	smart_ptr<DataSource> m_source;
	smart_ptr<DataTarget> m_target;
	bool m_isDCDLoad;
};

/*!
 * \brief Operation to execute code at a certain address.
 */
class ExecuteOperation : public Operation
{
public:
	enum execute_type_t
	{
		kJump,
		kCall
	};
	
public:
	ExecuteOperation() : Operation(), m_target(), m_argument(0), m_type(kCall), m_isHAB(false) {}

	inline void setTarget(DataTarget * target) { m_target = target; }
	inline DataTarget * getTarget() { return m_target; }
	
	inline void setArgument(uint32_t arg) { m_argument = arg; }
	inline uint32_t getArgument() { return m_argument; }
	
	inline void setExecuteType(execute_type_t type) { m_type = type; }
	inline execute_type_t getExecuteType() { return m_type; }
	
	inline void setIsHAB(bool isHAB) { m_isHAB = isHAB; }
	inline bool isHAB() const { return m_isHAB; }
	
protected:
	smart_ptr<DataTarget> m_target;
	uint32_t m_argument;
	execute_type_t m_type;
	bool m_isHAB;
};

/*!
 * \brief Authenticate with HAB and execute the entry point.
 */
class HABExecuteOperation : public ExecuteOperation
{
public:
	HABExecuteOperation() : ExecuteOperation() {}
};

/*!
 * \brief Operation to switch boot modes.
 */
class BootModeOperation : public Operation
{
public:
	BootModeOperation() : Operation() {}
	
	inline void setBootMode(uint32_t mode) { m_bootMode = mode; }
	inline uint32_t getBootMode() const { return m_bootMode; }

protected:
	uint32_t m_bootMode;	//!< The new boot mode value.
};

/*!
 * \brief Ordered sequence of operations.
 *
 * The operation objects owned by the sequence are \e not deleted when the
 * sequence is destroyed. The owner of the sequence must manually delete
 * the operation objects.
 */
class OperationSequence
{
public:
	typedef std::vector<Operation*> operation_list_t;	//!< Type for a list of operation objects.
	typedef operation_list_t::iterator iterator_t;	//!< Iterator over operations.
	typedef operation_list_t::const_iterator const_iterator_t;	//!< Const iterator over operations.

public:
	//! \brief Default constructor.
	OperationSequence() {}
	
	//! \brief Constructor. Makes a one-element sequence from \a soleElement.
	OperationSequence(Operation * soleElement) { m_operations.push_back(soleElement); }
	
	//! \brief Destructor.
	virtual ~OperationSequence();
	
	//! \name Iterators
	//@{
	inline iterator_t begin() { return m_operations.begin(); }
	inline const_iterator_t begin() const { return m_operations.begin(); }
	inline iterator_t end() { return m_operations.end(); }
	inline const_iterator_t end() const { return m_operations.end(); }
	//@}
	
	inline Operation * operator [] (unsigned index) const { return m_operations[index]; }
	
	//! \name Status
	//@{
	//! \brief Returns the number of operations in the sequence.
	inline unsigned getCount() const { return m_operations.size(); }
	//@}
	
	//! \name Operations
	//@{
	//! \brief Append one operation object to the sequence.
	inline void append(Operation * op) { m_operations.push_back(op); }
	
	//! \brief Append the contents of \a other onto this sequence.
	void append(const OperationSequence * other);
	
	//! \brief Appends \a other onto this sequence.
	OperationSequence & operator += (const OperationSequence * other) { append(other); return *this; }
	//@}

protected:
	operation_list_t m_operations;	//!< The list of operations.
};

}; // namespace elftosb

#endif // _Operation_h_