1711d51d8SMatt Spinler /**
2711d51d8SMatt Spinler  * Copyright © 2019 IBM Corporation
3711d51d8SMatt Spinler  *
4711d51d8SMatt Spinler  * Licensed under the Apache License, Version 2.0 (the "License");
5711d51d8SMatt Spinler  * you may not use this file except in compliance with the License.
6711d51d8SMatt Spinler  * You may obtain a copy of the License at
7711d51d8SMatt Spinler  *
8711d51d8SMatt Spinler  *     http://www.apache.org/licenses/LICENSE-2.0
9711d51d8SMatt Spinler  *
10711d51d8SMatt Spinler  * Unless required by applicable law or agreed to in writing, software
11711d51d8SMatt Spinler  * distributed under the License is distributed on an "AS IS" BASIS,
12711d51d8SMatt Spinler  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13711d51d8SMatt Spinler  * See the License for the specific language governing permissions and
14711d51d8SMatt Spinler  * limitations under the License.
15711d51d8SMatt Spinler  */
1603c1d915SMatt Spinler #include "user_header.hpp"
1703c1d915SMatt Spinler 
181a94cc38SMatt Spinler #include "pel_types.hpp"
19fdb6a202SMatt Spinler #include "severity.hpp"
201a94cc38SMatt Spinler 
2103c1d915SMatt Spinler #include <phosphor-logging/log.hpp>
2203c1d915SMatt Spinler 
2303c1d915SMatt Spinler namespace openpower
2403c1d915SMatt Spinler {
2503c1d915SMatt Spinler namespace pels
2603c1d915SMatt Spinler {
2703c1d915SMatt Spinler 
2803c1d915SMatt Spinler using namespace phosphor::logging;
2903c1d915SMatt Spinler 
30cf5a8d0fSMatt Spinler void UserHeader::unflatten(Stream& stream)
3103c1d915SMatt Spinler {
32cf5a8d0fSMatt Spinler     stream >> _header >> _eventSubsystem >> _eventScope >> _eventSeverity >>
33cf5a8d0fSMatt Spinler         _eventType >> _reserved4Byte1 >> _problemDomain >> _problemVector >>
34cf5a8d0fSMatt Spinler         _actionFlags >> _reserved4Byte2;
3503c1d915SMatt Spinler }
3603c1d915SMatt Spinler 
37cf5a8d0fSMatt Spinler void UserHeader::flatten(Stream& stream)
3803c1d915SMatt Spinler {
39cf5a8d0fSMatt Spinler     stream << _header << _eventSubsystem << _eventScope << _eventSeverity
40cf5a8d0fSMatt Spinler            << _eventType << _reserved4Byte1 << _problemDomain << _problemVector
41cf5a8d0fSMatt Spinler            << _actionFlags << _reserved4Byte2;
4203c1d915SMatt Spinler }
4303c1d915SMatt Spinler 
44fdb6a202SMatt Spinler UserHeader::UserHeader(const message::Entry& entry,
45fdb6a202SMatt Spinler                        phosphor::logging::Entry::Level severity)
46fdb6a202SMatt Spinler {
47fdb6a202SMatt Spinler     _header.id = static_cast<uint16_t>(SectionID::userHeader);
48fdb6a202SMatt Spinler     _header.size = UserHeader::flattenedSize();
49fdb6a202SMatt Spinler     _header.version = userHeaderVersion;
50fdb6a202SMatt Spinler     _header.subType = 0;
51fdb6a202SMatt Spinler     _header.componentID = static_cast<uint16_t>(ComponentID::phosphorLogging);
52fdb6a202SMatt Spinler 
53fdb6a202SMatt Spinler     _eventSubsystem = entry.subsystem;
54fdb6a202SMatt Spinler 
55fdb6a202SMatt Spinler     _eventScope = entry.eventScope.value_or(
56fdb6a202SMatt Spinler         static_cast<uint8_t>(EventScope::entirePlatform));
57fdb6a202SMatt Spinler 
58fdb6a202SMatt Spinler     // Get the severity from the registry if it's there, otherwise get it
59fdb6a202SMatt Spinler     // from the OpenBMC event log severity value.
60fdb6a202SMatt Spinler     _eventSeverity =
61fdb6a202SMatt Spinler         entry.severity.value_or(convertOBMCSeverityToPEL(severity));
62fdb6a202SMatt Spinler 
63fdb6a202SMatt Spinler     // TODO: ibm-dev/dev/#1144 Handle manufacturing sev & action flags
64fdb6a202SMatt Spinler 
65*f1e85e20SMatt Spinler     if (entry.eventType)
66*f1e85e20SMatt Spinler     {
67*f1e85e20SMatt Spinler         _eventType = *entry.eventType;
68*f1e85e20SMatt Spinler     }
69*f1e85e20SMatt Spinler     else
70*f1e85e20SMatt Spinler     {
71*f1e85e20SMatt Spinler         // There are different default event types for info errors
72*f1e85e20SMatt Spinler         // vs non info ones.
73*f1e85e20SMatt Spinler         auto sevType = static_cast<SeverityType>(_eventSeverity & 0xF0);
74*f1e85e20SMatt Spinler 
75*f1e85e20SMatt Spinler         _eventType = (sevType == SeverityType::nonError)
76*f1e85e20SMatt Spinler                          ? static_cast<uint8_t>(EventType::miscInformational)
77*f1e85e20SMatt Spinler                          : static_cast<uint8_t>(EventType::notApplicable);
78*f1e85e20SMatt Spinler     }
79fdb6a202SMatt Spinler 
80fdb6a202SMatt Spinler     _reserved4Byte1 = 0;
81fdb6a202SMatt Spinler 
82fdb6a202SMatt Spinler     // No uses for problem domain or vector
83fdb6a202SMatt Spinler     _problemDomain = 0;
84fdb6a202SMatt Spinler     _problemVector = 0;
85fdb6a202SMatt Spinler 
86*f1e85e20SMatt Spinler     // These will be cleaned up later in pel_rules::check()
87e07f915bSMatt Spinler     _actionFlags = entry.actionFlags.value_or(0);
88fdb6a202SMatt Spinler 
89fdb6a202SMatt Spinler     _reserved4Byte2 = 0;
90fdb6a202SMatt Spinler 
91fdb6a202SMatt Spinler     _valid = true;
92fdb6a202SMatt Spinler }
93fdb6a202SMatt Spinler 
9403c1d915SMatt Spinler UserHeader::UserHeader(Stream& pel)
9503c1d915SMatt Spinler {
9603c1d915SMatt Spinler     try
9703c1d915SMatt Spinler     {
98cf5a8d0fSMatt Spinler         unflatten(pel);
9903c1d915SMatt Spinler         validate();
10003c1d915SMatt Spinler     }
10103c1d915SMatt Spinler     catch (const std::exception& e)
10203c1d915SMatt Spinler     {
10303c1d915SMatt Spinler         log<level::ERR>("Cannot unflatten user header",
10403c1d915SMatt Spinler                         entry("ERROR=%s", e.what()));
10503c1d915SMatt Spinler         _valid = false;
10603c1d915SMatt Spinler     }
10703c1d915SMatt Spinler }
10803c1d915SMatt Spinler 
10903c1d915SMatt Spinler void UserHeader::validate()
11003c1d915SMatt Spinler {
11103c1d915SMatt Spinler     bool failed = false;
1121a94cc38SMatt Spinler     if (header().id != static_cast<uint16_t>(SectionID::userHeader))
11303c1d915SMatt Spinler     {
11403c1d915SMatt Spinler         log<level::ERR>("Invalid user header section ID",
11503c1d915SMatt Spinler                         entry("ID=0x%X", header().id));
11603c1d915SMatt Spinler         failed = true;
11703c1d915SMatt Spinler     }
11803c1d915SMatt Spinler 
11903c1d915SMatt Spinler     if (header().version != userHeaderVersion)
12003c1d915SMatt Spinler     {
12103c1d915SMatt Spinler         log<level::ERR>("Invalid user header version",
12203c1d915SMatt Spinler                         entry("VERSION=0x%X", header().version));
12303c1d915SMatt Spinler         failed = true;
12403c1d915SMatt Spinler     }
12503c1d915SMatt Spinler 
12603c1d915SMatt Spinler     _valid = (failed) ? false : true;
12703c1d915SMatt Spinler }
12803c1d915SMatt Spinler 
12903c1d915SMatt Spinler } // namespace pels
13003c1d915SMatt Spinler } // namespace openpower
131