From 5feb16d0738f57d220e5f2e6ba85e072c22135ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Wed, 17 Jan 2018 14:47:18 +0100 Subject: Update how configuration is handled in newdialog In previous implementation were dependencies described on two places. In NewDialog and in MachineConfig. Now NewDialog sets options in MachineConfig and configuration is then applied to NewDialog. --- qtmips_machine/machineconfig.cpp | 192 ++++++++++++++++++++++++++++++++++----- qtmips_machine/machineconfig.h | 50 ++++++++-- 2 files changed, 214 insertions(+), 28 deletions(-) (limited to 'qtmips_machine') 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 } diff --git a/qtmips_machine/machineconfig.h b/qtmips_machine/machineconfig.h index 10b8458..90c9b75 100644 --- a/qtmips_machine/machineconfig.h +++ b/qtmips_machine/machineconfig.h @@ -2,20 +2,35 @@ #define MACHINECONFIG_H #include +#include namespace machine { +enum ConfigPresets { + CP_SINGLE, + CP_PIPE_WITH_CACHE +}; + class MachineConfigCache { public: MachineConfigCache(); MachineConfigCache(const MachineConfigCache *cc); + MachineConfigCache(const QSettings*, const QString &prefix = ""); - // TODO + void store(QSettings*, const QString &prefix = ""); + + void preset(enum ConfigPresets); + + // If cache should be used or not + void set_enabled(bool); + + bool enabled() const; bool operator ==(const MachineConfigCache &c) const; bool operator !=(const MachineConfigCache &c) const; private: + bool en; // TODO }; @@ -23,6 +38,11 @@ class MachineConfig { public: MachineConfig(); MachineConfig(const MachineConfig *cc); + MachineConfig(const QSettings*, const QString &prefix = ""); + + void store(QSettings*, const QString &prefix = ""); + + void preset(enum ConfigPresets); enum HazardUnit { HU_NONE, @@ -36,29 +56,45 @@ public: // Configure if cpu should simulate delay slot in non-pipelined core // In default enabled. When disabled it also automatically disables pipelining. void set_delay_slot(bool); + // Hazard unit + void set_hazard_unit(enum HazardUnit); + // Protect data memory from execution. Only program sections can be executed. + void set_memory_execute_protection(bool); + // Protect program memory from accidental writes. + void set_memory_write_protection(bool); + // Set memory access times. Passed value is in cycles. + void set_memory_access_time_read(unsigned); + void set_memory_access_time_write(unsigned); // Set path to source elf file. This has to be set before core is initialized. void set_elf(QString path); // Configure cache void set_cache_program(const MachineConfigCache&); void set_cache_data(const MachineConfigCache&); - // Hazard unit - void set_hazard_unit(enum HazardUnit); bool pipelined() const; bool delay_slot() const; - QString elf() const; - MachineConfigCache cache_program() const; - MachineConfigCache cache_data() const; enum HazardUnit hazard_unit() const; + bool memory_execute_protection() const; + bool memory_write_protection() const; + unsigned memory_access_time_read() const; + unsigned memory_access_time_write() const; + QString elf() const; + const MachineConfigCache &cache_program() const; + const MachineConfigCache &cache_data() const; + + MachineConfigCache *access_cache_program(); + MachineConfigCache *access_cache_data(); bool operator ==(const MachineConfig &c) const; bool operator !=(const MachineConfig &c) const; private: bool pipeline, delayslot; + enum HazardUnit hunit; + bool exec_protect, write_protect; + unsigned mem_acc_read, mem_acc_write; QString elf_path; MachineConfigCache cch_program, cch_data; - enum HazardUnit hunit; }; } -- cgit v1.2.3