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