blob: b6c50f45cf22d2a5433de49cdc53e6250d901a1b [file] [log] [blame]
Deepak Kodihalli393821d2017-04-28 04:44:38 -05001#pragma once
2
3#include <vector>
4#include <memory>
5#include <numeric>
6#include <experimental/filesystem>
7#include "pnor_partition_defs.h"
8
9namespace openpower
10{
11namespace virtual_pnor
12{
13
14namespace fs = std::experimental::filesystem;
15
16using PartitionTable = std::vector<uint8_t>;
17using checksum_t = uint32_t;
18
19/** @brief Convert the input partition table to big endian.
20 *
21 * @param[in] src - reference to the pnor partition table
22 *
23 * @returns converted partition table
24 */
25PartitionTable endianFixup(const PartitionTable& src);
26
27namespace details
28{
29
30/** @brief Compute XOR-based checksum, by XORing consecutive words
31 * in the input data. Input must be aligned to word boundary.
32 *
33 * @param[in] data - input data on which checksum is computed
34 *
35 * @returns computed checksum
36 */
37template <class T>
38checksum_t checksum(const T& data)
39{
40 static_assert(sizeof(decltype(data)) % sizeof(checksum_t) == 0,
41 "sizeof(data) is not aligned to sizeof(checksum_t) boundary");
42
43 auto begin = reinterpret_cast<const checksum_t*>(&data);
44 auto end = begin + (sizeof(decltype(data)) / sizeof(checksum_t));
45
46 return std::accumulate(begin, end, 0, std::bit_xor<checksum_t>());
47}
48
49} // namespace details
50
51namespace partition
52{
53
54/** @class Table
55 * @brief Generates virtual PNOR partition table.
56 *
57 * Generates virtual PNOR partition table upon construction. Reads
58 * the PNOR information generated by this tool :
59 * github.com/openbmc/openpower-pnor-code-mgmt/blob/master/generate-squashfs,
60 * which generates a minimalistic table-of-contents (toc) file and
61 * individual files to represent various partitions that are of interest -
62 * these help form the "virtual" PNOR, which is typically a subset of the full
63 * PNOR image.
64 * These files are stored in a well-known location on the PNOR.
65 * Based on this information, this class prepares the partition table whose
66 * structure is as outlined in pnor_partition.h.
67 *
68 * The virtual PNOR supports 4KB erase blocks - partitions must be aligned to
69 * this size.
70 */
71class Table
72{
73 public:
74 /** @brief Constructor accepting the path of the directory
75 * that houses the PNOR partition files.
76 *
77 * @param[in] directory - path of the directory housing PNOR partitions
78 */
79 Table(fs::path&& directory);
80
81 Table();
82 Table(const Table&) = delete;
83 Table& operator=(const Table&) = delete;
84 Table(Table&&) = delete;
85 Table& operator=(Table&&) = delete;
86 ~Table() = default;
87
88 /** @brief Return size of partition table
89 *
90 * @returns size_t - size of partition table in blocks
91 */
92 size_t size() const
93 {
94 return szBlocks;
95 }
96
97 /** @brief Return a partition table having byte-ordering
98 * that the host expects.
99 *
100 * The host needs the partion table in big-endian.
101 *
102 * @returns const reference to host partition table.
103 */
104 const pnor_partition_table& getHostTable() const
105 {
106 return *(reinterpret_cast<
107 const pnor_partition_table*>(hostTbl.data()));
108 }
109
110 /** @brief Return a little-endian partition table
111 *
112 * @returns const reference to native partition table
113 */
114 const pnor_partition_table& getNativeTable() const
115 {
116 return *(reinterpret_cast<const pnor_partition_table*>(tbl.data()));
117 }
118
119 /** @brief Return partition corresponding to PNOR offset, the offset
120 * is within returned partition.
121 *
122 * @param[in] offset - PNOR offset in bytes
123 *
124 * @returns const reference to pnor_partition, if found, else a
125 * reference to a zeroed out pnor_partition structure.
126 */
127 const pnor_partition& partition(size_t offset) const;
128
129 private:
130 /** @brief Prepares a vector of PNOR partition structures.
131 */
132 void preparePartitions();
133
134 /** @brief Prepares the PNOR header.
135 */
136 void prepareHeader();
137
138 /** @brief Allocate memory to hold the partion table. Determine the
139 * amount needed based on the partition files in the toc file.
140 *
141 * @param[in] tocFile - Table of contents file path.
142 */
143 void allocateMemory(const fs::path& tocFile);
144
145 /** @brief Populate fields related to sizes for the input
146 * pnor_partition structure.
147 *
148 * @param[in/out] part - pnor_partition structure
149 * @param[in] start - partition start address
150 * @param[in] end - partition end address
151 */
152 void writeSizes(pnor_partition& part, size_t start, size_t end);
153
154 /** @brief Populate userdata bits for the input
155 * pnor_partition structure.
156 *
157 * @param[in/out] part - pnor_partition structure
158 * @param[in] data - string having userdata fields in a
159 * comma-separated line.
160 */
161 void writeUserdata(pnor_partition& part, const std::string& data);
162
163 /** @brief Populate the name and id fields for the input
164 * pnor_partition structure.
165 *
166 * @param[in/out] part - pnor_partition structure
167 * @param[in] name - partition name
168 * @param[id] id - partition id
169 */
170 void writeNameAndId(pnor_partition& part, std::string&& name,
171 const std::string& id);
172
173 /** @brief Populate default/unused fields for the input
174 * pnor_partition structure.
175 *
176 * @param[in/out] part - pnor_partition structure
177 */
178 void writeDefaults(pnor_partition& part);
179
180 /** @brief Return a little-endian partition table
181 *
182 * @returns reference to native partition table
183 */
184 pnor_partition_table& getNativeTable()
185 {
186 return *(reinterpret_cast<pnor_partition_table*>(tbl.data()));
187 }
188
189 /** @brief Size of the PNOR partition table -
190 * sizeof(pnor_partition_table) +
191 * (no. of partitions * sizeof(pnor_partition)),
192 * measured in erase-blocks.
193 */
194 size_t szBlocks;
195
196 /** @brief Size of virtual PNOR image, measured in erase-blocks */
197 size_t imgBlocks;
198
199 /** @brief Partition table */
200 PartitionTable tbl;
201
202 /** @brief Partition table with host byte ordering */
203 PartitionTable hostTbl;
204
205 /** @brief Directory housing generated PNOR partition files */
206 fs::path directory;
207
208 /** @brief Number of partitions */
209 size_t numParts;
210};
211
212} // namespace partition
213} // namespace virtual_pnor
214} // namespace openpower