#include #include #include #include #include #include #include #include namespace fs = std::filesystem; namespace analyzer { //------------------------------------------------------------------------------ void __getChipDataFiles(std::map& o_files) { o_files.clear(); auto directory = "/usr/share/openpower-libhei/"; for (const auto& entry : fs::directory_iterator(directory)) { auto path = entry.path(); std::ifstream file{path, std::ios::binary}; if (!file.good()) { trace::err("Unable to open file: %s", path.string().c_str()); continue; } // The first 8-bytes is the file keyword and the next 4-bytes is the // chip type. libhei::FileKeyword_t keyword; libhei::ChipType_t chipType; const size_t sz_keyword = sizeof(keyword); const size_t sz_chipType = sizeof(chipType); const size_t sz_buffer = sz_keyword + sz_chipType; // Read the keyword and chip type from the file. char buffer[sz_buffer]; file.read(buffer, sz_buffer); if (!file.good()) { trace::err("Unable to read file: %s", path.string().c_str()); continue; } // Get the keyword. memcpy(&keyword, &buffer[0], sz_keyword); keyword = be64toh(keyword); // Ensure the keyword value is correct. if (libhei::KW_CHIPDATA != keyword) { trace::err("Invalid chip data file: %s", path.string().c_str()); continue; } // Get the chip type. memcpy(&chipType, &buffer[sz_keyword], sz_chipType); chipType = be32toh(chipType); // Trace each legitimate chip data file for debug. trace::inf("File found: type=0x%0" PRIx32 " path=%s", chipType, path.string().c_str()); // So far, so good. Add the entry. auto ret = o_files.emplace(chipType, path); assert(ret.second); // Should not have duplicate entries } } //------------------------------------------------------------------------------ void __initialize(const fs::path& i_path) { // Get file size. const auto sz_buffer = fs::file_size(i_path); // Create a buffer large enough to hold the entire file. std::vector buffer(sz_buffer); // Open the chip data file. std::ifstream file{i_path, std::ios::binary}; assert(file.good()); // We've opened it once before, so it should open now. // Read the entire file into the buffer. file.read(buffer.data(), sz_buffer); assert(file.good()); // Again, this should be readable. // This is not necessary, but it frees up memory before calling the memory // intensive initialize() function. file.close(); // Initialize the isolator with this chip data file. libhei::initialize(buffer.data(), sz_buffer); } //------------------------------------------------------------------------------ void initializeIsolator(std::vector& o_chips) { // Get all of the active chips to be analyzed. util::pdbg::getActiveChips(o_chips); // Find all of the existing chip data files. std::map files; __getChipDataFiles(files); // Keep track of models/levels that have already been initialized. std::map initTypes; for (const auto& chip : o_chips) { auto chipType = chip.getType(); // Mark this chip type as initialized (or will be if it hasn't been). auto ret = initTypes.emplace(chipType, 1); if (!ret.second) { // This type has already been initialized. Nothing more to do. continue; } // Get the file for this chip. auto itr = files.find(chipType); // Ensure a chip data file exist for this chip. assert(files.end() != itr); // Initialize this chip type. __initialize(itr->second); } } //------------------------------------------------------------------------------ } // namespace analyzer