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" 19*c1489351SAatir #include "pel_values.hpp" 20fdb6a202SMatt Spinler #include "severity.hpp" 211a94cc38SMatt Spinler 22ad0e0476SAatir Manzur #include <iostream> 2303c1d915SMatt Spinler #include <phosphor-logging/log.hpp> 2403c1d915SMatt Spinler 2503c1d915SMatt Spinler namespace openpower 2603c1d915SMatt Spinler { 2703c1d915SMatt Spinler namespace pels 2803c1d915SMatt Spinler { 2903c1d915SMatt Spinler 30*c1489351SAatir namespace pv = openpower::pels::pel_values; 3103c1d915SMatt Spinler using namespace phosphor::logging; 3203c1d915SMatt Spinler 33cf5a8d0fSMatt Spinler void UserHeader::unflatten(Stream& stream) 3403c1d915SMatt Spinler { 35cf5a8d0fSMatt Spinler stream >> _header >> _eventSubsystem >> _eventScope >> _eventSeverity >> 36cf5a8d0fSMatt Spinler _eventType >> _reserved4Byte1 >> _problemDomain >> _problemVector >> 37cf5a8d0fSMatt Spinler _actionFlags >> _reserved4Byte2; 3803c1d915SMatt Spinler } 3903c1d915SMatt Spinler 400688545bSMatt Spinler void UserHeader::flatten(Stream& stream) const 4103c1d915SMatt Spinler { 42cf5a8d0fSMatt Spinler stream << _header << _eventSubsystem << _eventScope << _eventSeverity 43cf5a8d0fSMatt Spinler << _eventType << _reserved4Byte1 << _problemDomain << _problemVector 44cf5a8d0fSMatt Spinler << _actionFlags << _reserved4Byte2; 4503c1d915SMatt Spinler } 4603c1d915SMatt Spinler 47fdb6a202SMatt Spinler UserHeader::UserHeader(const message::Entry& entry, 48fdb6a202SMatt Spinler phosphor::logging::Entry::Level severity) 49fdb6a202SMatt Spinler { 50fdb6a202SMatt Spinler _header.id = static_cast<uint16_t>(SectionID::userHeader); 51fdb6a202SMatt Spinler _header.size = UserHeader::flattenedSize(); 52fdb6a202SMatt Spinler _header.version = userHeaderVersion; 53fdb6a202SMatt Spinler _header.subType = 0; 54fdb6a202SMatt Spinler _header.componentID = static_cast<uint16_t>(ComponentID::phosphorLogging); 55fdb6a202SMatt Spinler 56fdb6a202SMatt Spinler _eventSubsystem = entry.subsystem; 57fdb6a202SMatt Spinler 58fdb6a202SMatt Spinler _eventScope = entry.eventScope.value_or( 59fdb6a202SMatt Spinler static_cast<uint8_t>(EventScope::entirePlatform)); 60fdb6a202SMatt Spinler 61fdb6a202SMatt Spinler // Get the severity from the registry if it's there, otherwise get it 62fdb6a202SMatt Spinler // from the OpenBMC event log severity value. 63fdb6a202SMatt Spinler _eventSeverity = 64fdb6a202SMatt Spinler entry.severity.value_or(convertOBMCSeverityToPEL(severity)); 65fdb6a202SMatt Spinler 66fdb6a202SMatt Spinler // TODO: ibm-dev/dev/#1144 Handle manufacturing sev & action flags 67fdb6a202SMatt Spinler 68f1e85e20SMatt Spinler if (entry.eventType) 69f1e85e20SMatt Spinler { 70f1e85e20SMatt Spinler _eventType = *entry.eventType; 71f1e85e20SMatt Spinler } 72f1e85e20SMatt Spinler else 73f1e85e20SMatt Spinler { 74f1e85e20SMatt Spinler // There are different default event types for info errors 75f1e85e20SMatt Spinler // vs non info ones. 76f1e85e20SMatt Spinler auto sevType = static_cast<SeverityType>(_eventSeverity & 0xF0); 77f1e85e20SMatt Spinler 78f1e85e20SMatt Spinler _eventType = (sevType == SeverityType::nonError) 79f1e85e20SMatt Spinler ? static_cast<uint8_t>(EventType::miscInformational) 80f1e85e20SMatt Spinler : static_cast<uint8_t>(EventType::notApplicable); 81f1e85e20SMatt Spinler } 82fdb6a202SMatt Spinler 83fdb6a202SMatt Spinler _reserved4Byte1 = 0; 84fdb6a202SMatt Spinler 85fdb6a202SMatt Spinler // No uses for problem domain or vector 86fdb6a202SMatt Spinler _problemDomain = 0; 87fdb6a202SMatt Spinler _problemVector = 0; 88fdb6a202SMatt Spinler 89f1e85e20SMatt Spinler // These will be cleaned up later in pel_rules::check() 90e07f915bSMatt Spinler _actionFlags = entry.actionFlags.value_or(0); 91fdb6a202SMatt Spinler 92fdb6a202SMatt Spinler _reserved4Byte2 = 0; 93fdb6a202SMatt Spinler 94fdb6a202SMatt Spinler _valid = true; 95fdb6a202SMatt Spinler } 96fdb6a202SMatt Spinler 9703c1d915SMatt Spinler UserHeader::UserHeader(Stream& pel) 9803c1d915SMatt Spinler { 9903c1d915SMatt Spinler try 10003c1d915SMatt Spinler { 101cf5a8d0fSMatt Spinler unflatten(pel); 10203c1d915SMatt Spinler validate(); 10303c1d915SMatt Spinler } 10403c1d915SMatt Spinler catch (const std::exception& e) 10503c1d915SMatt Spinler { 10603c1d915SMatt Spinler log<level::ERR>("Cannot unflatten user header", 10703c1d915SMatt Spinler entry("ERROR=%s", e.what())); 10803c1d915SMatt Spinler _valid = false; 10903c1d915SMatt Spinler } 11003c1d915SMatt Spinler } 11103c1d915SMatt Spinler 11203c1d915SMatt Spinler void UserHeader::validate() 11303c1d915SMatt Spinler { 11403c1d915SMatt Spinler bool failed = false; 1151a94cc38SMatt Spinler if (header().id != static_cast<uint16_t>(SectionID::userHeader)) 11603c1d915SMatt Spinler { 11703c1d915SMatt Spinler log<level::ERR>("Invalid user header section ID", 11803c1d915SMatt Spinler entry("ID=0x%X", header().id)); 11903c1d915SMatt Spinler failed = true; 12003c1d915SMatt Spinler } 12103c1d915SMatt Spinler 12203c1d915SMatt Spinler if (header().version != userHeaderVersion) 12303c1d915SMatt Spinler { 12403c1d915SMatt Spinler log<level::ERR>("Invalid user header version", 12503c1d915SMatt Spinler entry("VERSION=0x%X", header().version)); 12603c1d915SMatt Spinler failed = true; 12703c1d915SMatt Spinler } 12803c1d915SMatt Spinler 12903c1d915SMatt Spinler _valid = (failed) ? false : true; 13003c1d915SMatt Spinler } 13103c1d915SMatt Spinler 132ad0e0476SAatir Manzur std::optional<std::string> UserHeader::getJSON() const 133ad0e0476SAatir Manzur { 134ad0e0476SAatir Manzur std::string severity; 135ad0e0476SAatir Manzur std::string subsystem; 136ad0e0476SAatir Manzur std::string eventScope; 137ad0e0476SAatir Manzur std::string eventType; 138*c1489351SAatir severity = pv::getValue(_eventSeverity, pel_values::severityValues); 139*c1489351SAatir subsystem = pv::getValue(_eventSubsystem, pel_values::subsystemValues); 140*c1489351SAatir eventScope = pv::getValue(_eventScope, pel_values::eventScopeValues); 141*c1489351SAatir eventType = pv::getValue(_eventType, pel_values::eventTypeValues); 142ad0e0476SAatir Manzur char tmpUhVal[8]; 143ad0e0476SAatir Manzur sprintf(tmpUhVal, "%d", userHeaderVersion); 144ad0e0476SAatir Manzur std::string uhVerStr(tmpUhVal); 145ad0e0476SAatir Manzur sprintf(tmpUhVal, "0x%X", _header.componentID); 146ad0e0476SAatir Manzur std::string uhCbStr(tmpUhVal); 147ad0e0476SAatir Manzur sprintf(tmpUhVal, "%d", _header.subType); 148ad0e0476SAatir Manzur std::string uhStStr(tmpUhVal); 149ad0e0476SAatir Manzur 150ad0e0476SAatir Manzur std::string uh = "{\"Section Version\": \"" + uhVerStr + 151ad0e0476SAatir Manzur "\"}, \n {\"Sub-section type\": \"" + uhStStr + 152ad0e0476SAatir Manzur "\"}, \n " 153ad0e0476SAatir Manzur "{\"Log Committed by\": \"" + 154ad0e0476SAatir Manzur uhCbStr + "\"}, \n {\"Subsystem\": \"" + subsystem + 155ad0e0476SAatir Manzur "\"},\n " 156ad0e0476SAatir Manzur "{\"Event Scope\": \"" + 157ad0e0476SAatir Manzur eventScope + "\"}, \n {\"Event Severity\":\"" + severity + 158ad0e0476SAatir Manzur "\"},\n {\"Event Type\": \"" + eventType + "\"}"; 159ad0e0476SAatir Manzur return uh; 160ad0e0476SAatir Manzur } 16103c1d915SMatt Spinler } // namespace pels 16203c1d915SMatt Spinler } // namespace openpower 163