Skip to content

Commit

Permalink
Merge branch 'jokap11-initSimpleMemRegion'
Browse files Browse the repository at this point in the history
  • Loading branch information
wysiwyng committed Jun 26, 2024
2 parents bd49a5b + 72f2226 commit 9033215
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 35 deletions.
49 changes: 17 additions & 32 deletions include/etiss/SimpleMemSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#include "etiss/System.h"
#include "etiss/make_unique.h"
#include <fstream>
#include <random>

#include <cstring>
#include <iostream>
Expand Down Expand Up @@ -88,48 +89,32 @@ class MemSegment
const etiss::uint64 size_;
access_t mode_;

/// @brief Constructor of Memory Segment
/// @param start_addr Start address of segment
/// @param size Size in bytes
/// @param mode Access Mode (R/W/X)
/// @param name Segment name
/// @param mem Pre-allocated Memory (not overwritten with initString)
/// @param initString String for initialization with imple_mem_system.memseg_initelement_ value: hex_string with 0x... / string /random options
/// @param InitEleSet Should self allocated MemSegment be initialized?
/// @param randomRoot If initString==Random use this value as generator root
MemSegment(etiss::uint64 start_addr, etiss::uint64 size, access_t mode, const std::string name,
etiss::uint8 *mem = nullptr)
: name_(name), start_addr_(start_addr), end_addr_(start_addr + size - 1), size_(size), mode_(mode)
{
if (mem)
{ // use reserved memory
mem_ = mem;
}
else
{
mem_ = new etiss::uint8[size];
self_allocated_ = true;
}
}
etiss::uint8 *mem = nullptr, std::string initString = "", bool InitEleSet = false, uint64_t randomRoot = 0);

// Can be overwritten afterwards with load_elf
void memInit(std::string initString, uint64_t randomRoot = 0);

virtual ~MemSegment(void)
{
if (self_allocated_ == true)
delete[] mem_;
}

void load(const void *data, size_t offset, size_t file_size_bytes)
{
if (data != nullptr && (offset + file_size_bytes) <= size_)
{
memcpy(mem_ + offset, data, file_size_bytes);
}
}
void load(const void *data, size_t offset, size_t file_size_bytes);

inline bool addr_in_range(etiss::uint64 addr) const
{
return ((addr >= start_addr_ && addr <= end_addr_) ? true : false);
}
inline bool addr_in_range(etiss::uint64 addr) const;

inline bool payload_in_range(etiss::uint64 addr, etiss::uint64 payload_size) const
{
if (addr_in_range(addr))
{
return (((addr + payload_size - 1) <= end_addr_) ? true : false);
}
return false;
}
inline bool payload_in_range(etiss::uint64 addr, etiss::uint64 payload_size) const;
};

/**
Expand Down
134 changes: 131 additions & 3 deletions src/SimpleMemSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,119 @@ uint32_t printMessage(std::string key, std::string message, uint32_t maxCount)
return count;
}

MemSegment::MemSegment(etiss::uint64 start_addr, etiss::uint64 size, access_t mode, const std::string name,
etiss::uint8 *mem, std::string initString, bool InitEleSet, uint64_t randomRoot)
: name_(name), start_addr_(start_addr), end_addr_(start_addr + size - 1), size_(size), mode_(mode)
{
if (mem)
{ // use reserved memory
mem_ = mem;
}
else
{
mem_ = new etiss::uint8[size];
if (InitEleSet)
{
memInit(initString, randomRoot);
}
else
{
std::stringstream memMsg;
memMsg << "The memory segment is allocated uninitialized with length 0x" << std::hex << size_ << " !";
etiss::log(etiss::INFO, memMsg.str());
}
self_allocated_ = true;
}
}

void MemSegment::memInit(std::string initString, uint64_t randomRoot) {
std::stringstream memMsg;

if (initString.find("0x") == 0)
{
memMsg << "The memory segment is initialized with 0x" << std::hex << size_ << " elements with hex value: " << initString;
etiss::log(etiss::INFO, memMsg.str());

// actual conversion from hex string to corresponding hex val
initString.erase(initString.begin(),initString.begin()+2);
const char* dataPtr;
size_t j{0};

for (etiss::uint64 i = 0; i < size_; ++i)
{
if (j != (initString.length() - 1))
{
dataPtr = initString.substr(j, 2).c_str();
}
else
{
dataPtr = initString.substr(j, 1).c_str();
}

j = (j + 2 <= initString.length() - 1) ? j + 2 : 0;

try
{
uint8_t hexVal = static_cast<uint8_t>(std::stoi(dataPtr, 0 ,16));
mem_[i] = hexVal;
}
catch (std::invalid_argument const& exp)
{
memMsg << "\n Hex Value MemSegment input is erronous (typo?) at " << exp.what();
etiss::log(etiss::FATALERROR, memMsg.str());
}
}
}

else if (initString.find("random") == 0 || initString.find("RANDOM") == 0)
{
memMsg << "The memory segment is initialized with 0x" << std::hex << size_ << " random bytes and root: " << randomRoot;
etiss::log(etiss::INFO, memMsg.str());

static std::default_random_engine generator{randomRoot};
std::uniform_int_distribution<int> random_char_{ 0, 255 };
for (etiss::uint64 i = 0; i < size_; ++i)
{
mem_[i] = random_char_(generator);
}

}

else
{
memMsg << "The memory segment is initialized with 0x" << std::hex << size_ << " elements with the string: " << initString;
etiss::log(etiss::INFO, memMsg.str());

const char* data = initString.c_str();
for (etiss::uint64 i = 0; i < size_; ++i)
{
mem_[i] = data[i%strlen(data)];
}
}
}

void MemSegment::load(const void *data, size_t offset, size_t file_size_bytes)
{
if (data != nullptr && (offset + file_size_bytes) <= size_)
{
memcpy(mem_ + offset, data, file_size_bytes);
}
}

inline bool MemSegment::addr_in_range(etiss::uint64 addr) const
{
return ((addr >= start_addr_ && addr <= end_addr_) ? true : false);
}

inline bool MemSegment::payload_in_range(etiss::uint64 addr, etiss::uint64 payload_size) const
{
if (addr_in_range(addr))
{
return (((addr + payload_size - 1) <= end_addr_) ? true : false);
}
return false;
}

void SimpleMemSystem::init_memory() {
load_segments();
load_elf();
Expand All @@ -97,6 +210,15 @@ void SimpleMemSystem::load_segments() {
}
std::stringstream().swap(ss);

ss << "simple_mem_system.memseg_initelement_" << std::setw(2) << std::setfill('0') << i;
std::string initString = etiss::cfg().get<std::string>(ss.str(), "");
bool initEleSet = etiss::cfg().isSet(ss.str());
std::stringstream().swap(ss);

ss << "simple_mem_system.memseg_initelement_random_root_" << std::setw(2) << std::setfill('0') << i;
uint64_t randomRoot = etiss::cfg().get<uint64_t>(ss.str(), 0);
std::stringstream().swap(ss);

ss << "simple_mem_system.memseg_image_" << std::setw(2) << std::setfill('0') << i;
std::string image = etiss::cfg().get<std::string>(ss.str(), "");
std::stringstream().swap(ss);
Expand Down Expand Up @@ -131,8 +253,8 @@ void SimpleMemSystem::load_segments() {
etiss::uint8 *buf = nullptr;
size_t fsize = 0;

if (image != "")
{

if (image != "") {
std::ifstream ifs(image, std::ifstream::binary | std::ifstream::ate);
if (!ifs) {
std::stringstream msg;
Expand All @@ -145,10 +267,16 @@ void SimpleMemSystem::load_segments() {
buf = new etiss::uint8[fsize];

ifs.read((char*)buf, fsize);

std::stringstream mem_msg;
mem_msg << "The memory segment " << i << " is initialized with 0x" << std::hex << length << " bytes from input_image !";
etiss::log(etiss::INFO, mem_msg.str());
}

auto mseg = std::make_unique<MemSegment>(origin, length, static_cast<MemSegment::access_t>(access), sname.str(), nullptr);
auto mseg = std::make_unique<MemSegment>(origin, length, static_cast<MemSegment::access_t>(access), sname.str(),
buf, initString, initEleSet, randomRoot);
add_memsegment(mseg, buf, fsize);
delete[] buf;
}
}
}
Expand Down

0 comments on commit 9033215

Please sign in to comment.