blob: 8d00ae54ddb7fb7081ccd05ba78e3d570ad6de7c [file] [log] [blame]
Zane Shelleyf4bd5ff2020-11-05 22:26:04 -06001
2#include <assert.h>
3
4#include <hei_main.hpp>
5#include <util/pdbg.hpp>
6#include <util/trace.hpp>
7
8#include <filesystem>
9#include <fstream>
10#include <map>
11#include <vector>
12
13namespace fs = std::filesystem;
14
15namespace analyzer
16{
17
18//------------------------------------------------------------------------------
19
20void __getChipDataFiles(std::map<libhei::ChipType_t, fs::path>& o_files)
21{
22 o_files.clear();
23
24 auto directory = "/usr/share/openpower-libhei/";
25
26 for (const auto& entry : fs::directory_iterator(directory))
27 {
28 auto path = entry.path();
29
30 std::ifstream file{path, std::ios::binary};
31 if (!file.good())
32 {
33 trace::err("Unable to open file: %s", path.string().c_str());
34 continue;
35 }
36
37 // The first 8-bytes is the file keyword and the next 4-bytes is the
38 // chip type.
39 libhei::FileKeyword_t keyword;
40 libhei::ChipType_t chipType;
41
Patrick Williams27dd6362023-05-10 07:51:20 -050042 const size_t sz_keyword = sizeof(keyword);
Zane Shelleyf4bd5ff2020-11-05 22:26:04 -060043 const size_t sz_chipType = sizeof(chipType);
Patrick Williams27dd6362023-05-10 07:51:20 -050044 const size_t sz_buffer = sz_keyword + sz_chipType;
Zane Shelleyf4bd5ff2020-11-05 22:26:04 -060045
46 // Read the keyword and chip type from the file.
47 char buffer[sz_buffer];
48 file.read(buffer, sz_buffer);
49 if (!file.good())
50 {
51 trace::err("Unable to read file: %s", path.string().c_str());
52 continue;
53 }
54
55 // Get the keyword.
56 memcpy(&keyword, &buffer[0], sz_keyword);
57 keyword = be64toh(keyword);
58
59 // Ensure the keyword value is correct.
60 if (libhei::KW_CHIPDATA != keyword)
61 {
62 trace::err("Invalid chip data file: %s", path.string().c_str());
63 continue;
64 }
65
66 // Get the chip type.
67 memcpy(&chipType, &buffer[sz_keyword], sz_chipType);
68 chipType = be32toh(chipType);
69
70 // Trace each legitimate chip data file for debug.
71 trace::inf("File found: type=0x%0" PRIx32 " path=%s", chipType,
72 path.string().c_str());
73
74 // So far, so good. Add the entry.
75 auto ret = o_files.emplace(chipType, path);
76 assert(ret.second); // Should not have duplicate entries
77 }
78}
79
80//------------------------------------------------------------------------------
81
82void __initialize(const fs::path& i_path)
83{
84 // Get file size.
85 const auto sz_buffer = fs::file_size(i_path);
86
87 // Create a buffer large enough to hold the entire file.
88 std::vector<char> buffer(sz_buffer);
89
90 // Open the chip data file.
91 std::ifstream file{i_path, std::ios::binary};
92 assert(file.good()); // We've opened it once before, so it should open now.
93
94 // Read the entire file into the buffer.
95 file.read(buffer.data(), sz_buffer);
96 assert(file.good()); // Again, this should be readable.
97
98 // This is not necessary, but it frees up memory before calling the memory
99 // intensive initialize() function.
100 file.close();
101
102 // Initialize the isolator with this chip data file.
103 libhei::initialize(buffer.data(), sz_buffer);
104}
105
106//------------------------------------------------------------------------------
107
Zane Shelley171a2e02020-11-13 13:56:13 -0600108void initializeIsolator(std::vector<libhei::Chip>& o_chips)
Zane Shelleyf4bd5ff2020-11-05 22:26:04 -0600109{
Zane Shelley171a2e02020-11-13 13:56:13 -0600110 // Get all of the active chips to be analyzed.
111 util::pdbg::getActiveChips(o_chips);
112
Zane Shelleyf4bd5ff2020-11-05 22:26:04 -0600113 // Find all of the existing chip data files.
114 std::map<libhei::ChipType_t, fs::path> files;
115 __getChipDataFiles(files);
116
117 // Keep track of models/levels that have already been initialized.
118 std::map<libhei::ChipType_t, unsigned int> initTypes;
119
Zane Shelley171a2e02020-11-13 13:56:13 -0600120 for (const auto& chip : o_chips)
Zane Shelleyf4bd5ff2020-11-05 22:26:04 -0600121 {
122 auto chipType = chip.getType();
123
Zane Shelleyf4bd5ff2020-11-05 22:26:04 -0600124 // Mark this chip type as initialized (or will be if it hasn't been).
125 auto ret = initTypes.emplace(chipType, 1);
126 if (!ret.second)
127 {
128 // This type has already been initialized. Nothing more to do.
129 continue;
130 }
131
132 // Get the file for this chip.
133 auto itr = files.find(chipType);
134
135 // Ensure a chip data file exist for this chip.
136 assert(files.end() != itr);
137
138 // Initialize this chip type.
139 __initialize(itr->second);
140 }
141}
142
143//------------------------------------------------------------------------------
144
145} // namespace analyzer