blob: c5532cb0806f486455dde7bae8de96700011285c [file] [log] [blame]
Alexander Hansen40fb5492025-10-28 17:56:12 +01001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright 2020 IBM Corporation
3
Matt Spinler386a61e2020-08-13 15:51:12 -05004#include "extended_user_data.hpp"
5
6#include "pel_types.hpp"
7#ifdef PELTOOL
8#include "user_data_json.hpp"
9#endif
Arya K Padman5bc26532024-04-10 06:19:25 -050010#include <phosphor-logging/lg2.hpp>
Matt Spinler7f1b9052022-03-22 09:18:58 -050011
Jayanth Othayoth1aa90d42023-09-13 04:25:45 -050012#include <format>
13
Matt Spinler386a61e2020-08-13 15:51:12 -050014namespace openpower::pels
15{
16
Matt Spinler386a61e2020-08-13 15:51:12 -050017void ExtendedUserData::unflatten(Stream& stream)
18{
19 stream >> _header;
20
21 if (_header.size <= SectionHeader::flattenedSize() + 4)
22 {
23 throw std::out_of_range(
Jayanth Othayoth1aa90d42023-09-13 04:25:45 -050024 std::format("ExtendedUserData::unflatten: SectionHeader::size {} "
Matt Spinler386a61e2020-08-13 15:51:12 -050025 "too small",
26 _header.size));
27 }
28
29 size_t dataLength = _header.size - 4 - SectionHeader::flattenedSize();
30 _data.resize(dataLength);
31
32 stream >> _creatorID >> _reserved1B >> _reserved2B >> _data;
33}
34
35void ExtendedUserData::flatten(Stream& stream) const
36{
37 stream << _header << _creatorID << _reserved1B << _reserved2B << _data;
38}
39
40ExtendedUserData::ExtendedUserData(Stream& pel)
41{
42 try
43 {
44 unflatten(pel);
45 validate();
46 }
47 catch (const std::exception& e)
48 {
Arya K Padman5bc26532024-04-10 06:19:25 -050049 lg2::error("Cannot unflatten ExtendedUserData section: {EXCEPTION}",
50 "EXCEPTION", e);
Matt Spinler386a61e2020-08-13 15:51:12 -050051 _valid = false;
52 }
53}
54
55ExtendedUserData::ExtendedUserData(uint16_t componentID, uint8_t subType,
56 uint8_t version, uint8_t creatorID,
57 const std::vector<uint8_t>& data)
58{
59 _header.id = static_cast<uint16_t>(SectionID::extUserData);
60 _header.version = version;
61 _header.subType = subType;
62 _header.componentID = componentID;
63
64 _creatorID = creatorID;
65 _reserved1B = 0;
66 _reserved2B = 0;
67 _data = data;
68 _header.size = flattenedSize();
69 _valid = true;
70}
71
72void ExtendedUserData::validate()
73{
74 if (header().id != static_cast<uint16_t>(SectionID::extUserData))
75 {
Arya K Padman5bc26532024-04-10 06:19:25 -050076 lg2::error("Invalid ExtendedUserData section ID: {HEADER_ID}",
77 "HEADER_ID", lg2::hex, header().id);
Matt Spinler386a61e2020-08-13 15:51:12 -050078 _valid = false;
79 }
80 else
81 {
82 _valid = true;
83 }
84}
85
Patrick Williams075c7922024-08-16 15:19:49 -040086std::optional<std::string> ExtendedUserData::getJSON(
87 uint8_t /*creatorID*/,
88 const std::vector<std::string>& plugins [[maybe_unused]]) const
Matt Spinler386a61e2020-08-13 15:51:12 -050089{
90 // Use the creator ID value from the section.
91#ifdef PELTOOL
92 return user_data::getJSON(_header.componentID, _header.subType,
93 _header.version, _data, _creatorID, plugins);
94#endif
95 return std::nullopt;
96}
97
98bool ExtendedUserData::shrink(size_t newSize)
99{
100 // minimum size is 8B header + 4B of fields + 4B of data
Matt Spinlere2eb14a2025-05-09 13:34:51 -0500101 if ((newSize < flattenedSize()) && (newSize >= (Section::headerSize() + 8)))
Matt Spinler386a61e2020-08-13 15:51:12 -0500102 {
Matt Spinlere2eb14a2025-05-09 13:34:51 -0500103 auto dataSize = newSize - Section::headerSize() - 4;
Matt Spinler386a61e2020-08-13 15:51:12 -0500104
105 // Ensure it's 4B aligned
106 _data.resize((dataSize / 4) * 4);
107 _header.size = flattenedSize();
108 return true;
109 }
110
111 return false;
112}
113
114} // namespace openpower::pels