blob: d470822fa84c401a74d84e9371c8656d52227786 [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
Andrew Jefferyd394a782018-02-21 16:16:14 +103027/** @brief Parse a ToC line (entry) into the corresponding FFS partition
28 * object.
29 *
30 * @param[in] line - The ToC line to parse
31 * @param[in] blockSize - The flash block size in bytes
32 * @param[out] part - The partition object to populate with the information
33 * parsed from the provided ToC line
34 *
35 * @returns True on success, false on failure.
36 */
37bool parseTocLine(const std::string& line, size_t blockSize,
38 pnor_partition& part);
39
Deepak Kodihalli393821d2017-04-28 04:44:38 -050040namespace details
41{
42
43/** @brief Compute XOR-based checksum, by XORing consecutive words
44 * in the input data. Input must be aligned to word boundary.
45 *
46 * @param[in] data - input data on which checksum is computed
47 *
48 * @returns computed checksum
49 */
Andrew Jefferyf34db312018-03-09 15:27:03 +103050template <class T> checksum_t checksum(const T& data)
Deepak Kodihalli393821d2017-04-28 04:44:38 -050051{
52 static_assert(sizeof(decltype(data)) % sizeof(checksum_t) == 0,
53 "sizeof(data) is not aligned to sizeof(checksum_t) boundary");
54
55 auto begin = reinterpret_cast<const checksum_t*>(&data);
56 auto end = begin + (sizeof(decltype(data)) / sizeof(checksum_t));
57
58 return std::accumulate(begin, end, 0, std::bit_xor<checksum_t>());
59}
60
61} // namespace details
62
63namespace partition
64{
65
66/** @class Table
67 * @brief Generates virtual PNOR partition table.
68 *
69 * Generates virtual PNOR partition table upon construction. Reads
70 * the PNOR information generated by this tool :
71 * github.com/openbmc/openpower-pnor-code-mgmt/blob/master/generate-squashfs,
72 * which generates a minimalistic table-of-contents (toc) file and
73 * individual files to represent various partitions that are of interest -
74 * these help form the "virtual" PNOR, which is typically a subset of the full
75 * PNOR image.
76 * These files are stored in a well-known location on the PNOR.
77 * Based on this information, this class prepares the partition table whose
78 * structure is as outlined in pnor_partition.h.
79 *
80 * The virtual PNOR supports 4KB erase blocks - partitions must be aligned to
81 * this size.
82 */
83class Table
84{
Andrew Jefferyf34db312018-03-09 15:27:03 +103085 public:
86 /** @brief Constructor accepting the path of the directory
87 * that houses the PNOR partition files.
88 *
89 * @param[in] directory - path of the directory housing PNOR partitions
90 * @param[in] blockSize - PNOR block size, in bytes. See
91 * open-power/hostboot/blob/master/src/usr/pnor/ffs.h for
92 * the PNOR FFS structure.
93 * @param[in] pnorSize - PNOR size, in bytes
94 */
95 Table(fs::path&& directory, size_t blockSize, size_t pnorSize);
Deepak Kodihalli393821d2017-04-28 04:44:38 -050096
Andrew Jefferyf34db312018-03-09 15:27:03 +103097 /** @brief Constructor - creates partition table
98 *
99 * @param[in] blockSize - PNOR block size, in bytes
100 * @param[in] pnorSize - PNOR size, in bytes
101 */
102 Table(size_t blockSize, size_t pnorSize);
Deepak Kodihallid1d79302017-07-11 23:01:39 -0500103
Andrew Jefferyf34db312018-03-09 15:27:03 +1030104 Table(const Table&) = delete;
105 Table& operator=(const Table&) = delete;
106 Table(Table&&) = delete;
107 Table& operator=(Table&&) = delete;
108 ~Table() = default;
Deepak Kodihalli393821d2017-04-28 04:44:38 -0500109
Andrew Jefferyf34db312018-03-09 15:27:03 +1030110 /** @brief Return size of partition table
111 *
112 * @returns size_t - size of partition table in blocks
113 */
114 size_t size() const
115 {
116 return szBlocks;
117 }
Deepak Kodihalli393821d2017-04-28 04:44:38 -0500118
Andrew Jefferyf34db312018-03-09 15:27:03 +1030119 /** @brief Return a partition table having byte-ordering
120 * that the host expects.
121 *
122 * The host needs the partion table in big-endian.
123 *
124 * @returns const reference to host partition table.
125 */
126 const pnor_partition_table& getHostTable() const
127 {
128 return *(reinterpret_cast<const pnor_partition_table*>(hostTbl.data()));
129 }
Deepak Kodihalli393821d2017-04-28 04:44:38 -0500130
Andrew Jefferyf34db312018-03-09 15:27:03 +1030131 /** @brief Return a little-endian partition table
132 *
133 * @returns const reference to native partition table
134 */
135 const pnor_partition_table& getNativeTable() const
136 {
137 return *(reinterpret_cast<const pnor_partition_table*>(tbl.data()));
138 }
Deepak Kodihalli393821d2017-04-28 04:44:38 -0500139
Andrew Jefferyf34db312018-03-09 15:27:03 +1030140 /** @brief Return partition corresponding to PNOR offset, the offset
141 * is within returned partition.
142 *
143 * @param[in] offset - PNOR offset in bytes
144 *
145 * @returns const reference to pnor_partition, if found, else an
146 * exception will be thrown.
147 */
148 const pnor_partition& partition(size_t offset) const;
Deepak Kodihalli393821d2017-04-28 04:44:38 -0500149
Andrew Jefferyf34db312018-03-09 15:27:03 +1030150 /** @brief Return partition corresponding to input partition name.
151 *
152 * @param[in] name - PNOR partition name
153 *
154 * @returns const reference to pnor_partition, if found, else an
155 * exception will be thrown.
156 */
157 const pnor_partition& partition(const std::string& name) const;
Deepak Kodihalli8a899692017-07-11 23:17:19 -0500158
Andrew Jefferyf34db312018-03-09 15:27:03 +1030159 private:
160 /** @brief Prepares a vector of PNOR partition structures.
161 */
162 void preparePartitions();
Deepak Kodihalli393821d2017-04-28 04:44:38 -0500163
Andrew Jefferyf34db312018-03-09 15:27:03 +1030164 /** @brief Prepares the PNOR header.
165 */
166 void prepareHeader();
Deepak Kodihalli393821d2017-04-28 04:44:38 -0500167
Andrew Jefferyf34db312018-03-09 15:27:03 +1030168 /** @brief Allocate memory to hold the partion table. Determine the
169 * amount needed based on the partition files in the toc file.
170 *
171 * @param[in] tocFile - Table of contents file path.
172 */
173 void allocateMemory(const fs::path& tocFile);
Deepak Kodihalli393821d2017-04-28 04:44:38 -0500174
Andrew Jefferyf34db312018-03-09 15:27:03 +1030175 /** @brief Return a little-endian partition table
176 *
177 * @returns reference to native partition table
178 */
179 pnor_partition_table& getNativeTable()
180 {
181 return *(reinterpret_cast<pnor_partition_table*>(tbl.data()));
182 }
Deepak Kodihalli393821d2017-04-28 04:44:38 -0500183
Andrew Jefferyf34db312018-03-09 15:27:03 +1030184 /** @brief Size of the PNOR partition table -
185 * sizeof(pnor_partition_table) +
186 * (no. of partitions * sizeof(pnor_partition)),
187 * measured in erase-blocks.
188 */
189 size_t szBlocks;
Deepak Kodihalli393821d2017-04-28 04:44:38 -0500190
Andrew Jefferyf34db312018-03-09 15:27:03 +1030191 /** @brief Partition table */
192 PartitionTable tbl;
Deepak Kodihalli393821d2017-04-28 04:44:38 -0500193
Andrew Jefferyf34db312018-03-09 15:27:03 +1030194 /** @brief Partition table with host byte ordering */
195 PartitionTable hostTbl;
Deepak Kodihalli393821d2017-04-28 04:44:38 -0500196
Andrew Jefferyf34db312018-03-09 15:27:03 +1030197 /** @brief Directory housing generated PNOR partition files */
198 fs::path directory;
Deepak Kodihalli393821d2017-04-28 04:44:38 -0500199
Andrew Jefferyf34db312018-03-09 15:27:03 +1030200 /** @brief Number of partitions */
201 size_t numParts;
Deepak Kodihallid1d79302017-07-11 23:01:39 -0500202
Andrew Jefferyf34db312018-03-09 15:27:03 +1030203 /** @brief PNOR block size, in bytes */
204 size_t blockSize;
Deepak Kodihallid1d79302017-07-11 23:01:39 -0500205
Andrew Jefferyf34db312018-03-09 15:27:03 +1030206 /** @brief PNOR size, in bytes */
207 size_t pnorSize;
Deepak Kodihalli393821d2017-04-28 04:44:38 -0500208};
209
210} // namespace partition
211} // namespace virtual_pnor
212} // namespace openpower