xref: /openbmc/bios-bmc-smm-error-logger/src/rde/rde_dictionary_manager.cpp (revision 1a64356f6dc40bfbc76594a51df1ec3f32bbbd69)
1  #include "rde/rde_dictionary_manager.hpp"
2  
3  #include <stdplus/print.hpp>
4  
5  #include <format>
6  
7  namespace bios_bmc_smm_error_logger
8  {
9  namespace rde
10  {
11  
DictionaryManager()12  DictionaryManager::DictionaryManager() : validDictionaryCount(0) {}
13  
startDictionaryEntry(uint32_t resourceId,const std::span<const uint8_t> data)14  void DictionaryManager::startDictionaryEntry(
15      uint32_t resourceId, const std::span<const uint8_t> data)
16  {
17      // Check whether the resourceId is already available.
18      auto itemIt = dictionaries.find(resourceId);
19      if (itemIt == dictionaries.end())
20      {
21          dictionaries[resourceId] =
22              std::make_unique<DictionaryEntry>(false, data);
23          return;
24      }
25  
26      // Since we are creating a new dictionary on an existing entry, invalidate
27      // the existing entry.
28      invalidateDictionaryEntry(*itemIt->second);
29  
30      // Flush the existing data.
31      itemIt->second->data.clear();
32      itemIt->second->data.insert(itemIt->second->data.begin(), data.begin(),
33                                  data.end());
34  }
35  
markDataComplete(uint32_t resourceId)36  bool DictionaryManager::markDataComplete(uint32_t resourceId)
37  {
38      auto itemIt = dictionaries.find(resourceId);
39      if (itemIt == dictionaries.end())
40      {
41          stdplus::print(stderr, "Resource ID {} not found.\n", resourceId);
42          return false;
43      }
44      validateDictionaryEntry(*itemIt->second);
45      return true;
46  }
47  
addDictionaryData(uint32_t resourceId,const std::span<const uint8_t> data)48  bool DictionaryManager::addDictionaryData(uint32_t resourceId,
49                                            const std::span<const uint8_t> data)
50  {
51      auto itemIt = dictionaries.find(resourceId);
52      if (itemIt == dictionaries.end())
53      {
54          stdplus::print(stderr, "Resource ID {} not found.\n", resourceId);
55          return false;
56      }
57      // Since we are modifying an existing entry, invalidate the existing entry.
58      invalidateDictionaryEntry(*itemIt->second);
59      itemIt->second->data.insert(itemIt->second->data.end(), data.begin(),
60                                  data.end());
61      return true;
62  }
63  
64  std::optional<std::span<const uint8_t>>
getDictionary(uint32_t resourceId)65      DictionaryManager::getDictionary(uint32_t resourceId)
66  {
67      auto itemIt = dictionaries.find(resourceId);
68      if (itemIt == dictionaries.end())
69      {
70          stdplus::print(stderr, "Resource ID {} not found.\n", resourceId);
71          return std::nullopt;
72      }
73  
74      if (!itemIt->second->valid)
75      {
76          stdplus::print(stderr,
77                         "Requested an incomplete dictionary. Resource ID {}\n",
78                         resourceId);
79          return std::nullopt;
80      }
81      return itemIt->second->data;
82  }
83  
84  std::optional<std::span<const uint8_t>>
getAnnotationDictionary()85      DictionaryManager::getAnnotationDictionary()
86  {
87      return getDictionary(annotationResourceId);
88  }
89  
getDictionaryCount()90  uint32_t DictionaryManager::getDictionaryCount()
91  {
92      return validDictionaryCount;
93  }
94  
invalidateDictionaries()95  void DictionaryManager::invalidateDictionaries()
96  {
97      // We won't flush the existing data. The data will be flushed if a new entry
98      // is added for an existing resource ID.
99      for (const auto& element : dictionaries)
100      {
101          element.second->valid = false;
102      }
103      validDictionaryCount = 0;
104  }
105  
invalidateDictionaryEntry(DictionaryEntry & entry)106  void DictionaryManager::invalidateDictionaryEntry(DictionaryEntry& entry)
107  {
108      // If this is a valid entry, reduce the valid dictionary count.
109      if (entry.valid)
110      {
111          --validDictionaryCount;
112      }
113      entry.valid = false;
114  }
115  
validateDictionaryEntry(DictionaryEntry & entry)116  void DictionaryManager::validateDictionaryEntry(DictionaryEntry& entry)
117  {
118      if (!entry.valid)
119      {
120          ++validDictionaryCount;
121      }
122      entry.valid = true;
123  }
124  
125  } // namespace rde
126  } // namespace bios_bmc_smm_error_logger
127