blob: ebb2b1986ff1b1586f0d477d1f5b72b4a25bf34f [file] [log] [blame]
Patrick Ventureab296412020-12-30 13:39:37 -08001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
Brad Bishope45d8c72022-05-25 15:12:53 -040016/// \file fru_utils.hpp
Patrick Ventureab296412020-12-30 13:39:37 -080017
18#pragma once
Zev Weiss309c0b12022-02-25 01:44:12 +000019#include "fru_reader.hpp"
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053020#include <boost/container/flat_map.hpp>
Patrick Ventureab296412020-12-30 13:39:37 -080021
22#include <cstdint>
23#include <functional>
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053024#include <regex>
Patrick Ventureab296412020-12-30 13:39:37 -080025#include <string>
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053026#include <utility>
Patrick Ventureab296412020-12-30 13:39:37 -080027#include <vector>
Patrick Ventureab296412020-12-30 13:39:37 -080028extern "C"
29{
30// Include for I2C_SMBUS_BLOCK_MAX
31#include <linux/i2c.h>
32}
33
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053034constexpr size_t fruBlockSize = 8;
35
Kumar Thangavelc74e7512022-02-03 22:53:05 +053036using DeviceMap = boost::container::flat_map<int, std::vector<uint8_t>>;
37using BusMap = boost::container::flat_map<int, std::shared_ptr<DeviceMap>>;
38
39inline BusMap busMap;
40
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053041enum class DecodeState
42{
43 ok,
44 end,
45 err,
46};
47
48enum class resCodes
49{
50 resOK,
51 resWarn,
52 resErr
53};
54
Patrick Ventureab296412020-12-30 13:39:37 -080055enum class fruAreas
56{
57 fruAreaInternal = 0,
58 fruAreaChassis,
59 fruAreaBoard,
60 fruAreaProduct,
61 fruAreaMultirecord
62};
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053063
Ed Tanous07d467b2021-02-23 14:48:37 -080064const std::vector<std::string> fruAreaNames = {"INTERNAL", "CHASSIS", "BOARD",
65 "PRODUCT", "MULTIRECORD"};
66const std::regex nonAsciiRegex("[^\x01-\x7f]");
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053067
Ed Tanous07d467b2021-02-23 14:48:37 -080068const std::vector<std::string> chassisFruAreas = {"PART_NUMBER",
69 "SERIAL_NUMBER"};
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053070
Ed Tanous07d467b2021-02-23 14:48:37 -080071const std::vector<std::string> boardFruAreas = {"MANUFACTURER", "PRODUCT_NAME",
72 "SERIAL_NUMBER", "PART_NUMBER",
73 "FRU_VERSION_ID"};
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053074
Ed Tanous07d467b2021-02-23 14:48:37 -080075const std::vector<std::string> productFruAreas = {
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053076 "MANUFACTURER", "PRODUCT_NAME", "PART_NUMBER", "VERSION",
77 "SERIAL_NUMBER", "ASSET_TAG", "FRU_VERSION_ID"};
78
Ed Tanous07d467b2021-02-23 14:48:37 -080079const std::string fruCustomFieldName = "INFO_AM";
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053080
Patrick Ventureab296412020-12-30 13:39:37 -080081inline fruAreas operator++(fruAreas& x)
82{
83 return x = static_cast<fruAreas>(std::underlying_type<fruAreas>::type(x) +
84 1);
85}
86
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053087inline const std::string& getFruAreaName(fruAreas area)
88{
Ed Tanous07d467b2021-02-23 14:48:37 -080089 return fruAreaNames[static_cast<unsigned int>(area)];
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053090}
91
Ed Tanous07d467b2021-02-23 14:48:37 -080092std::tm intelEpoch(void);
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053093
94char sixBitToChar(uint8_t val);
95
96/* 0xd - 0xf are reserved values, but not fatal; use a placeholder char. */
97const char bcdHighChars[] = {
98 ' ', '-', '.', 'X', 'X', 'X',
99};
100
101char bcdPlusToChar(uint8_t val);
102
103bool verifyOffset(const std::vector<uint8_t>& fruBytes, fruAreas currentArea,
104 uint8_t len);
105
106std::pair<DecodeState, std::string>
107 decodeFRUData(std::vector<uint8_t>::const_iterator& iter,
108 const std::vector<uint8_t>::const_iterator& end,
109 bool isLangEng);
110
111bool checkLangEng(uint8_t lang);
112
113resCodes
Michael Shen0961b112022-02-22 11:06:33 +0800114 formatIPMIFRU(const std::vector<uint8_t>& fruBytes,
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +1030115 boost::container::flat_map<std::string, std::string>& result);
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +0530116
117std::vector<uint8_t>& getFRUInfo(const uint8_t& bus, const uint8_t& address);
118
119uint8_t calculateChecksum(std::vector<uint8_t>::const_iterator iter,
120 std::vector<uint8_t>::const_iterator end);
121
122uint8_t calculateChecksum(std::vector<uint8_t>& fruAreaData);
123
124unsigned int updateFRUAreaLenAndChecksum(std::vector<uint8_t>& fruData,
125 size_t fruAreaStart,
126 size_t fruAreaEndOfFieldsOffset,
127 size_t fruAreaEndOffset);
128
129ssize_t getFieldLength(uint8_t fruFieldTypeLenValue);
130
Oskar Senftbd4075f2021-10-05 23:42:43 -0400131/// \brief Find a FRU header.
Zev Weiss309c0b12022-02-25 01:44:12 +0000132/// \param reader the FRUReader to read via
Oskar Senftbd4075f2021-10-05 23:42:43 -0400133/// \param errorHelp and a helper string for failures
134/// \param blockData buffer to return the last read block
135/// \param baseOffset the offset to start the search at;
136/// set to 0 to perform search;
137/// returns the offset at which a header was found
138/// \return whether a header was found
Zev Weiss309c0b12022-02-25 01:44:12 +0000139bool findFRUHeader(FRUReader& reader, const std::string& errorHelp,
Oskar Senftbd4075f2021-10-05 23:42:43 -0400140 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX>& blockData,
Zev Weiss1525e852022-03-22 22:27:43 +0000141 off_t& baseOffset);
Oskar Senftbd4075f2021-10-05 23:42:43 -0400142
Patrick Ventureab296412020-12-30 13:39:37 -0800143/// \brief Read and validate FRU contents.
Zev Weiss309c0b12022-02-25 01:44:12 +0000144/// \param reader the FRUReader to read via
Patrick Ventureab296412020-12-30 13:39:37 -0800145/// \param errorHelp and a helper string for failures
146/// \return the FRU contents from the file
Zev Weiss309c0b12022-02-25 01:44:12 +0000147std::vector<uint8_t> readFRUContents(FRUReader& reader,
Patrick Ventureab296412020-12-30 13:39:37 -0800148 const std::string& errorHelp);
149
150/// \brief Validate an IPMI FRU common header
151/// \param blockData the bytes comprising the common header
152/// \return true if valid
153bool validateHeader(const std::array<uint8_t, I2C_SMBUS_BLOCK_MAX>& blockData);
154
155/// \brief Get offset for a common header area
156/// \param area - the area
157/// \return the field offset
158unsigned int getHeaderAreaFieldOffset(fruAreas area);