aboutsummaryrefslogtreecommitdiff
path: root/qtmips_machine/machineconfig.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qtmips_machine/machineconfig.cpp')
-rw-r--r--qtmips_machine/machineconfig.cpp192
1 files changed, 171 insertions, 21 deletions
diff --git a/qtmips_machine/machineconfig.cpp b/qtmips_machine/machineconfig.cpp
index e479d66..ab6f2a5 100644
--- a/qtmips_machine/machineconfig.cpp
+++ b/qtmips_machine/machineconfig.cpp
@@ -2,17 +2,64 @@
using namespace machine;
+//////////////////////////////////////////////////////////////////////////////
+/// Default config of MachineConfig
+#define DF_PIPELINE false
+#define DF_DELAYSLOT true
+#define DF_HUNIT HU_STALL_FORWARD
+#define DF_EXEC_PROTEC false
+#define DF_WRITE_PROTEC false
+#define DF_MEM_ACC_READ 10
+#define DF_MEM_ACC_WRITE 10
+#define DF_ELF QString("")
+//////////////////////////////////////////////////////////////////////////////
+/// Default config of MachineConfigCache
+#define DFC_EN false
+//////////////////////////////////////////////////////////////////////////////
+
MachineConfigCache::MachineConfigCache() {
- // TODO
+ en = DFC_EN;
}
MachineConfigCache::MachineConfigCache(const MachineConfigCache *cc) {
- // TODO
+ en = cc->enabled();
+}
+
+#define N(STR) (prefix + QString(STR))
+
+MachineConfigCache::MachineConfigCache(const QSettings *sts, const QString &prefix) {
+ en = sts->value(N("Enabled"), DFC_EN).toBool();
+}
+
+void MachineConfigCache::store(QSettings *sts, const QString &prefix) {
+ sts->setValue(N("Enabled"), en);
+}
+
+#undef N
+
+void MachineConfigCache::preset(enum ConfigPresets p) {
+ switch (p) {
+ case CP_SINGLE:
+ set_enabled(false);
+ break;
+ case CP_PIPE_WITH_CACHE:
+ set_enabled(false);
+ break;
+ }
+}
+
+void MachineConfigCache::set_enabled(bool v) {
+ en = v;
+}
+
+bool MachineConfigCache::enabled() const {
+ return en;
}
bool MachineConfigCache::operator==(const MachineConfigCache &c) const {
- // TODO
- return true;
+#define CMP(GETTER) (GETTER)() == (c.GETTER)()
+ return CMP(enabled);
+#undef CMP
}
bool MachineConfigCache::operator!=(const MachineConfigCache &c) const {
@@ -20,18 +67,77 @@ bool MachineConfigCache::operator!=(const MachineConfigCache &c) const {
}
MachineConfig::MachineConfig() {
- pipeline = false;
- delayslot = true;
- hunit = HU_STALL_FORWARD;
+ pipeline = DF_PIPELINE;
+ delayslot = DF_DELAYSLOT;
+ hunit = DF_HUNIT;
+ exec_protect = DF_EXEC_PROTEC;
+ write_protect = DF_WRITE_PROTEC;
+ mem_acc_read = DF_MEM_ACC_READ;
+ mem_acc_write = DF_MEM_ACC_WRITE;
+ elf_path = DF_ELF;
+ cch_program = MachineConfigCache();
+ cch_data = MachineConfigCache();
}
MachineConfig::MachineConfig(const MachineConfig *cc) {
pipeline = cc->pipelined();
delayslot = cc->delay_slot();
+ hunit = cc->hazard_unit();
+ exec_protect = cc->memory_execute_protection();
+ write_protect = cc->memory_write_protection();
+ mem_acc_read = cc->memory_access_time_read();
+ mem_acc_write = cc->memory_access_time_write();
elf_path = cc->elf();
cch_program = cc->cache_program();
cch_data = cc->cache_data();
- hunit = cc->hazard_unit();
+}
+
+#define N(STR) (prefix + QString(STR))
+
+MachineConfig::MachineConfig(const QSettings *sts, const QString &prefix) {
+ pipeline = sts->value(N("Pipelined"), DF_PIPELINE).toBool();
+ delayslot = sts->value(N("DelaySlot"), DF_DELAYSLOT).toBool();
+ hunit = (enum HazardUnit)sts->value(N("HazardUnit"), DF_HUNIT).toUInt(); // TODO probably rather save as string
+ exec_protect = sts->value(N("MemoryExecuteProtection"), DF_EXEC_PROTEC).toBool();
+ write_protect = sts->value(N("MemoryWriteProtection"), DF_WRITE_PROTEC).toBool();
+ mem_acc_read = sts->value(N("MemoryRead"), DF_MEM_ACC_READ).toUInt();
+ mem_acc_write = sts->value(N("MemoryWrite"), DF_MEM_ACC_WRITE).toUInt();
+ elf_path = sts->value(N("Elf"), DF_ELF).toString();
+ cch_program = MachineConfigCache(sts, N("ProgramCache_"));
+ cch_data = MachineConfigCache(sts, N("DataCache_"));
+}
+
+void MachineConfig::store(QSettings *sts, const QString &prefix) {
+ sts->setValue(N("Pipelined"), pipelined());
+ sts->setValue(N("DelaySlot"), delay_slot());
+ sts->setValue(N("HazardUnit"), (unsigned)hazard_unit());
+ sts->setValue(N("Elf"), elf_path);
+ cch_program.store(sts, N("ProgramCache_"));
+ cch_data.store(sts, N("DataCache_"));
+}
+
+#undef N
+
+void MachineConfig::preset(enum ConfigPresets p) {
+ // Note: we set just a minimal subset to get preset (preserving as much of hidden configuration as possible)
+ switch (p) {
+ case CP_SINGLE:
+ set_pipelined(false);
+ set_delay_slot(true);
+ break;
+ case CP_PIPE_WITH_CACHE:
+ set_pipelined(true);
+ set_hazard_unit(MachineConfig::HU_STALL_FORWARD);
+ break;
+ }
+ // Some common configurations
+ set_memory_execute_protection(DF_EXEC_PROTEC);
+ set_memory_write_protection(DF_WRITE_PROTEC);
+ set_memory_access_time_read(DF_MEM_ACC_READ);
+ set_memory_access_time_write(DF_MEM_ACC_WRITE);
+
+ access_cache_program()->preset(p);
+ access_cache_data()->preset(p);
}
void MachineConfig::set_pipelined(bool v) {
@@ -40,8 +146,26 @@ void MachineConfig::set_pipelined(bool v) {
void MachineConfig::set_delay_slot(bool v) {
delayslot = v;
- if (!delayslot)
- pipeline = false;
+}
+
+void MachineConfig::set_hazard_unit(enum MachineConfig::HazardUnit hu) {
+ hunit = hu;
+}
+
+void MachineConfig::set_memory_execute_protection(bool v) {
+ exec_protect = v;
+}
+
+void MachineConfig::set_memory_write_protection(bool v) {
+ write_protect = v;
+}
+
+void MachineConfig::set_memory_access_time_read(unsigned v) {
+ mem_acc_read = v;
+}
+
+void MachineConfig::set_memory_access_time_write(unsigned v) {
+ mem_acc_write = v;
}
void MachineConfig::set_elf(QString path) {
@@ -56,42 +180,68 @@ void MachineConfig::set_cache_data(const MachineConfigCache &c) {
cch_data = c;
}
-void MachineConfig::set_hazard_unit(enum MachineConfig::HazardUnit hu) {
- hunit = hu;
-}
-
bool MachineConfig::pipelined() const {
return pipeline;
}
bool MachineConfig::delay_slot() const {
- return delayslot;
+ // Delay slot is always on when pipeline is enabled
+ return pipeline || delayslot;
+}
+
+enum MachineConfig::HazardUnit MachineConfig::hazard_unit() const {
+ // Hazard unit is always off when there is no pipeline
+ return pipeline ? hunit : machine::MachineConfig::HU_NONE;
+}
+
+bool MachineConfig::memory_execute_protection() const {
+ return exec_protect;
+}
+
+bool MachineConfig::memory_write_protection() const {
+ return write_protect;
+}
+
+unsigned MachineConfig::memory_access_time_read() const {
+ return mem_acc_read;
+}
+
+unsigned MachineConfig::memory_access_time_write() const {
+ return mem_acc_write;
}
QString MachineConfig::elf() const {
return elf_path;
}
-MachineConfigCache MachineConfig::cache_program() const {
+const MachineConfigCache &MachineConfig::cache_program() const {
return cch_program;
}
-MachineConfigCache MachineConfig::cache_data() const {
+const MachineConfigCache &MachineConfig::cache_data() const {
return cch_data;
}
-enum MachineConfig::HazardUnit MachineConfig::hazard_unit() const {
- return hunit;
+MachineConfigCache *MachineConfig::access_cache_program() {
+ return &cch_program;
+}
+
+MachineConfigCache *MachineConfig::access_cache_data() {
+ return &cch_data;
}
bool MachineConfig::operator==(const MachineConfig &c) const {
#define CMP(GETTER) (GETTER)() == (c.GETTER)()
return CMP(pipelined) && \
CMP(delay_slot) && \
+ CMP(hazard_unit) && \
+ CMP(memory_execute_protection) && \
+ CMP(memory_write_protection) && \
+ CMP(memory_access_time_read) && \
+ CMP(memory_access_time_write) && \
CMP(elf) && \
CMP(cache_program) && \
- CMP(cache_data) && \
- CMP(hazard_unit);
+ CMP(cache_data);
#undef CMP
}