blob: 8d00ae54ddb7fb7081ccd05ba78e3d570ad6de7c [file] [log] [blame]
#include <assert.h>
#include <hei_main.hpp>
#include <util/pdbg.hpp>
#include <util/trace.hpp>
#include <filesystem>
#include <fstream>
#include <map>
#include <vector>
namespace fs = std::filesystem;
namespace analyzer
{
//------------------------------------------------------------------------------
void __getChipDataFiles(std::map<libhei::ChipType_t, fs::path>& 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<char> 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<libhei::Chip>& 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<libhei::ChipType_t, fs::path> files;
__getChipDataFiles(files);
// Keep track of models/levels that have already been initialized.
std::map<libhei::ChipType_t, unsigned int> 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