Skip to content

Commit

Permalink
Use void properties for cpuregs and vector properties for image loading
Browse files Browse the repository at this point in the history
  • Loading branch information
janweinstock committed Jun 24, 2023
1 parent 3787e91 commit be737b9
Show file tree
Hide file tree
Showing 12 changed files with 57 additions and 108 deletions.
2 changes: 1 addition & 1 deletion include/vcml/core/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class processor : public component, protected debugging::target
debugging::gdbserver* m_gdb;

unordered_map<unsigned int, irq_stats> m_irq_stats;
unordered_map<u64, property_base*> m_regprops;
unordered_map<u64, property<void>*> m_regprops;

bool cmd_dump(const vector<string>& args, ostream& os);
bool cmd_read(const vector<string>& args, ostream& os);
Expand Down
2 changes: 1 addition & 1 deletion include/vcml/debugging/loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class loader
void load_image(const string& filename, u64 offset, image_type type);
void load_image(const image_info& image);

void load_images(const string& images);
void load_images(const vector<string>& images);
void load_images(const vector<image_info>& images);

static loader* find(const string& name);
Expand Down
2 changes: 1 addition & 1 deletion include/vcml/models/generic/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class memory : public peripheral, public debugging::loader
property<bool> discard_writes;
property<bool> readonly;
property<string> shared;
property<string> images;
property<vector<string>> images;
property<u8> poison;

tlm_target_socket in;
Expand Down
5 changes: 3 additions & 2 deletions include/vcml/models/meta/loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ namespace meta {
class loader : public component, public debugging::loader
{
public:
property<string> images;
property<vector<string>> images;

tlm_initiator_socket insn;
tlm_initiator_socket data;

loader(const sc_module_name& nm, const string& images = "");
loader(const sc_module_name& nm);
loader(const sc_module_name& nm, const vector<string>& images);
virtual ~loader();
VCML_KIND(loader);

Expand Down
35 changes: 22 additions & 13 deletions include/vcml/properties/property.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,11 @@ inline const char* property<T, N>::str() const {

m_str = "";

for (size_t i = 0; i < (N - 1); i++)
m_str += escape(to_string<T>(m_value[i]), delim) + delim;
m_str += escape(to_string<T>(m_value[N - 1]), delim);
if (N > 0) {
for (size_t i = 0; i < (N - 1); i++)
m_str += escape(to_string<T>(m_value[i]), delim) + delim;
m_str += escape(to_string<T>(m_value[N - 1]), delim);
}

return m_str.c_str();
}
Expand Down Expand Up @@ -540,9 +542,11 @@ inline const char* property<void, N>::str() const {

m_str = "";

for (size_t i = 0; i < m_count - 1; i++)
m_str += escape(to_string(get(i)), delim) + delim;
m_str += escape(to_string(get(m_count - 1)), delim);
if (m_count > 0) {
for (size_t i = 0; i < m_count - 1; i++)
m_str += escape(to_string(get(i)), delim) + delim;
m_str += escape(to_string(get(m_count - 1)), delim);
}

return m_str.c_str();
}
Expand All @@ -552,16 +556,16 @@ inline void property<void, N>::str(const string& s) {
m_inited = true;

vector<string> args = split(s);
size_t size = args.size();
size_t count = args.size();

if (size < m_size) {
if (count < m_count) {
log_warn("property %s has not enough initializers", name().c_str());
} else if (size > m_size) {
} else if (count > m_count) {
log_warn("property %s has too many initializers", name().c_str());
}

u8* ptr = m_data;
for (size_t i = 0; i < min(m_size, size); i++, ptr += m_size) {
for (size_t i = 0; i < min(m_count, count); i++, ptr += m_size) {
u64 val = from_string<u64>(trim(args[i]));
if (mwr::encode_size(val) / 8u > m_size) {
log_warn("property %s initialization value too big: 0x%llx",
Expand Down Expand Up @@ -667,6 +671,9 @@ class property<vector<T>, 1> : public property_base
void set_default(vector<T>&& def);
void inherit_default();

operator const vector<T>&() const { return get(); }
operator vector<T>&() { return get(); }

const T& operator[](size_t idx) const { return get(idx); }
T& operator[](size_t idx) { return get(idx); }

Expand Down Expand Up @@ -741,9 +748,11 @@ inline const char* property<vector<T>, 1>::str() const {

m_str = "";

for (size_t i = 0; i < count() - 1; i++)
m_str += escape(to_string(get(i)), delim) + delim;
m_str += escape(to_string(get(count() - 1)), delim);
if (count() > 0) {
for (size_t i = 0; i < count() - 1; i++)
m_str += escape(to_string(get(i)), delim) + delim;
m_str += escape(to_string(get(count() - 1)), delim);
}

return m_str.c_str();
}
Expand Down
2 changes: 1 addition & 1 deletion include/vcml/ui/console.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class console
unordered_set<shared_ptr<display>> m_displays;

public:
property<string> displays;
property<vector<string>> displays;

bool has_display() const { return !m_displays.empty(); }

Expand Down
91 changes: 12 additions & 79 deletions src/vcml/core/processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -542,30 +542,14 @@ void processor::fetch_cpuregs() {
const debugging::cpureg* reg = find_cpureg(it.first);
VCML_ERROR_ON(!reg, "no cpureg %llu", it.first);

property_base* prop = it.second;
auto* prop = it.second;
VCML_ERROR_ON(!prop, "no propery for cpureg %llu", it.first);

u64 val = 0;
if (reg->is_readable())
val = reg->read();

switch (reg->size) {
case 1:
dynamic_cast<property<u8>*>(prop)->set((u8)val);
break;
case 2:
dynamic_cast<property<u16>*>(prop)->set((u16)val);
break;
case 4:
dynamic_cast<property<u32>*>(prop)->set((u32)val);
break;
case 8:
dynamic_cast<property<u64>*>(prop)->set((u64)val);
break;
default:
VCML_ERROR("register %s has illegal size: %llu bytes",
reg->name.c_str(), reg->size);
}
prop->set(val);
}
}

Expand All @@ -574,30 +558,13 @@ void processor::flush_cpuregs() {
const debugging::cpureg* reg = find_cpureg(it.first);
VCML_ERROR_ON(!reg, "no cpureg %llu", it.first);

property_base* prop = it.second;
auto* prop = it.second;
VCML_ERROR_ON(!prop, "no propery for cpureg %llu", it.first);

if (!reg->is_writeable())
continue;

u64 val = 0;
switch (reg->size) {
case 1:
val = dynamic_cast<property<u8>*>(prop)->get();
break;
case 2:
val = dynamic_cast<property<u16>*>(prop)->get();
break;
case 4:
val = dynamic_cast<property<u32>*>(prop)->get();
break;
case 8:
val = dynamic_cast<property<u64>*>(prop)->get();
break;
default:
VCML_ERROR("register %s has illegal size: %llu bytes",
reg->name.c_str(), reg->size);
}
u64 val = prop->get();

const u64 mask = bitmask(reg->width());
if (reg->size < 8 && val > mask) {
Expand All @@ -622,47 +589,31 @@ void processor::define_cpuregs(const vector<debugging::cpureg>& regs) {
VCML_ERROR("cannot read cpureg %s", regnm);
}

property_base*& prop = m_regprops[reg.regno];
auto*& prop = m_regprops[reg.regno];
VCML_ERROR_ON(prop, "property %s already exists", regnm);

switch (reg.size) {
case 1:
prop = new property<u8>(regnm, defval);
break;
case 2:
prop = new property<u16>(regnm, defval);
break;
case 4:
prop = new property<u32>(regnm, defval);
break;
case 8:
prop = new property<u64>(regnm, defval);
break;
default:
VCML_ERROR("cpureg %s has illegal size %llu", regnm, reg.size);
}
prop = new property<void>(regnm, reg.size, 1);
}

log_debug("defined %zu cpu registers", regs.size());
flush_cpuregs();
}

bool processor::read_reg_dbg(vcml::u64 idx, vcml::u64& val) {
bool processor::read_reg_dbg(vcml::u64 idx, u64& val) {
return false; // to be overloaded
}

bool processor::write_reg_dbg(vcml::u64 idx, vcml::u64 val) {
bool processor::write_reg_dbg(vcml::u64 idx, u64 val) {
return false; // to be overloaded
}

bool processor::read_cpureg_dbg(const cpureg& reg, vcml::u64& val) {
bool processor::read_cpureg_dbg(const cpureg& reg, u64& val) {
if (!reg.is_readable())
return false;

return read_reg_dbg(reg.regno, val);
}

bool processor::write_cpureg_dbg(const cpureg& reg, vcml::u64 val) {
bool processor::write_cpureg_dbg(const cpureg& reg, u64 val) {
if (!reg.is_writeable())
return false;

Expand All @@ -673,26 +624,8 @@ bool processor::write_cpureg_dbg(const cpureg& reg, vcml::u64 val) {
if (it == m_regprops.end())
VCML_ERROR("no propery for cpureg %s", reg.name.c_str());

property_base* prop = it->second;

switch (reg.size) {
case 1:
dynamic_cast<property<u8>*>(prop)->set((u8)val);
break;
case 2:
dynamic_cast<property<u16>*>(prop)->set((u16)val);
break;
case 4:
dynamic_cast<property<u32>*>(prop)->set((u32)val);
break;
case 8:
dynamic_cast<property<u64>*>(prop)->set((u64)val);
break;
default:
VCML_ERROR("register %s has illegal size: %llu bytes",
reg.name.c_str(), reg.size);
}

auto* prop = it->second;
prop->set(val);
return true;
}

Expand Down
7 changes: 3 additions & 4 deletions src/vcml/debugging/loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,9 @@ image_type detect_image_type(const string& filename) {
return IMAGE_BIN;
}

vector<image_info> images_from_string(const string& s) {
vector<image_info> images_from_string(const vector<string>& vec) {
vector<image_info> images;
vector<string> token = split(s);
for (string cur : token) {
for (string cur : vec) {
cur = trim(cur);
if (cur.empty())
continue;
Expand Down Expand Up @@ -242,7 +241,7 @@ void loader::load_image(const image_info& image) {
}
}

void loader::load_images(const string& files) {
void loader::load_images(const vector<string>& files) {
auto images = images_from_string(files);
load_images(images);
}
Expand Down
2 changes: 1 addition & 1 deletion src/vcml/models/generic/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ memory::memory(const sc_module_name& nm, u64 sz, bool read_only, alignment al,
discard_writes("discard_writes", false),
readonly("readonly", read_only),
shared("shared", ""),
images("images", ""),
images("images"),
poison("poison", 0x00),
in("in") {
VCML_ERROR_ON(size == 0u, "memory size cannot be 0");
Expand Down
10 changes: 9 additions & 1 deletion src/vcml/models/meta/loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,15 @@
namespace vcml {
namespace meta {

loader::loader(const sc_module_name& nm, const string& imginit):
loader::loader(const sc_module_name& nm):
component(nm),
debugging::loader(*this, true),
images("images"),
insn("insn"),
data("data") {
}

loader::loader(const sc_module_name& nm, const vector<string>& imginit):
component(nm),
debugging::loader(*this, true),
images("images", imginit),
Expand Down
5 changes: 2 additions & 3 deletions src/vcml/ui/console.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ namespace vcml {
namespace ui {

console::console():
m_keyboards(), m_pointers(), m_displays(), displays("displays", "") {
vector<string> types = split(displays);
for (const string& type : types) {
m_keyboards(), m_pointers(), m_displays(), displays("displays") {
for (const string& type : displays) {
try {
auto disp = display::lookup(type);
if (disp)
Expand Down
2 changes: 1 addition & 1 deletion test/models/meta_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class loader_test : public test_base
dmem("dmem", 0x2000),
ibus("ibus"),
dbus("dbus"),
loader("loader", get_resource_path("elf.elf")) {
loader("loader", { get_resource_path("elf.elf") }) {
ibus.bind(loader.insn);
ibus.bind(imem.in, { 0x400000, 0x400fff });

Expand Down

0 comments on commit be737b9

Please sign in to comment.