diff options
Diffstat (limited to 'qtmips_machine')
| -rw-r--r-- | qtmips_machine/cache.cpp | 84 | ||||
| -rw-r--r-- | qtmips_machine/cache.h | 5 | ||||
| -rw-r--r-- | qtmips_machine/memory.cpp | 19 | ||||
| -rw-r--r-- | qtmips_machine/memory.h | 12 | ||||
| -rw-r--r-- | qtmips_machine/peripheral.cpp | 3 | ||||
| -rw-r--r-- | qtmips_machine/peripheral.h | 2 | ||||
| -rw-r--r-- | qtmips_machine/physaddrspace.cpp | 4 | ||||
| -rw-r--r-- | qtmips_machine/physaddrspace.h | 2 | 
8 files changed, 82 insertions, 49 deletions
diff --git a/qtmips_machine/cache.cpp b/qtmips_machine/cache.cpp index 742cdb5..30771b0 100644 --- a/qtmips_machine/cache.cpp +++ b/qtmips_machine/cache.cpp @@ -75,15 +75,17 @@ Cache::Cache(MemoryAccess  *m, const MachineConfigCache *cc, unsigned memory_acc              replc.lfu[row] = new unsigned[cnf.associativity()];              for (unsigned int  i = 0; i < cnf.associativity(); i++)                   replc.lfu[row][i] = 0; -	} +        }          break;      case MachineConfigCache::RP_LRU: -        replc.lru = new time_t*[cnf.sets()]; +        replc.lru = new unsigned int*[cnf.sets()];          for (unsigned int row = 0; row < cnf.sets(); row++) { -            replc.lru[row] = new time_t[cnf.associativity()]; +            replc.lru[row] = new unsigned int[cnf.associativity()];              for (unsigned int i = 0; i < cnf.associativity(); i++)                  replc.lru[row][i] = 0; -	} +        } +        break; +    case MachineConfigCache::RP_RAND:      default:          break;      } @@ -138,12 +140,17 @@ bool Cache::wword(std::uint32_t address, std::uint32_t value) {      return changed;  } -std::uint32_t Cache::rword(std::uint32_t address) const { +std::uint32_t Cache::rword(std::uint32_t address, bool debug_access) const {      if (!cnf.enabled() ||          (address >= uncached_start && address <= uncached_last)) { -        return mem->read_word(address); +        return mem->read_word(address, debug_access);      } +    if (debug_access) { +        if (!(location_status(address) & LOCSTAT_CACHED)) +            return mem->read_word(address, debug_access); +        return debug_rword(address); +    }      std::uint32_t data;      access(address, &data, false);      return data; @@ -236,16 +243,25 @@ enum LocationStatus Cache::location_status(std::uint32_t address) const {      return mem->location_status(address);  } +std::uint32_t Cache::debug_rword(std::uint32_t address) const { +    std::uint32_t row, col, tag; +    compute_row_col_tag(row, col, tag, address); +    for (unsigned indx = 0; indx < cnf.associativity(); indx++) +        if (dt[indx][row].valid && dt[indx][row].tag == tag) +            return dt[indx][row].data[col]; +    return 0; +} +  bool Cache::access(std::uint32_t address, std::uint32_t *data, bool write, std::uint32_t value) const {      bool changed = false;      std::uint32_t row, col, tag;      compute_row_col_tag(row, col, tag, address);      unsigned indx = 0; -    // Try to locate exact block or some unused one -    while (indx < cnf.associativity() && dt[indx][row].valid && dt[indx][row].tag != tag) +    // Try to locate exact block +    while (indx < cnf.associativity() && (!dt[indx][row].valid || dt[indx][row].tag != tag))          indx++; -    // Replace block +    // Need to find new block      if (indx >= cnf.associativity()) {          // We have to kick something          switch (cnf.replacement_policy()) { @@ -254,26 +270,37 @@ bool Cache::access(std::uint32_t address, std::uint32_t *data, bool write, std::              break;          case MachineConfigCache::RP_LFU:              { -            unsigned lowest = replc.lfu[row][0]; -            indx = 0; -            for (unsigned i = 1; i < cnf.associativity(); i++) -                if (lowest > replc.lfu[row][i]) { -                    lowest = replc.lfu[row][i]; -                    indx = i; +                unsigned lowest = replc.lfu[row][0]; +                indx = 0; +                for (unsigned i = 1; i < cnf.associativity(); i++) { +                    if (!dt[i][row].valid) { +                        indx = i; +                        break; +                    } +                    if (lowest > replc.lfu[row][i]) { +                        lowest = replc.lfu[row][i]; +                        indx = i; +                    }                  } +                break;              } -            break;          case MachineConfigCache::RP_LRU:              { -            time_t lowest = replc.lru[row][0]; -            indx = 0; -            for (unsigned i = 1; i < cnf.associativity(); i++) -                if (lowest > replc.lru[row][i]) { -                    lowest = replc.lru[row][i]; -                    indx = i; +                unsigned int least = 0xffff; +                indx = 0; +                for (unsigned i = 0; i < cnf.associativity(); i++) { +                    if (!dt[i][row].valid) { +                        // found free one, use it directly +                        indx = i; +                        break; +                    } +                    if (least < replc.lru[row][i]) { +                        least = replc.lru[row][i]; +                        indx = i; +                    }                  } +                break;              } -            break;          }      }      SANITY_ASSERT(indx < cnf.associativity(), "Probably unimplemented replacement policy"); @@ -307,13 +334,17 @@ bool Cache::access(std::uint32_t address, std::uint32_t *data, bool write, std::          }      } -    // Update replc +    // Update replcement data      switch (cnf.replacement_policy()) {      case MachineConfigCache::RP_LFU: -        replc.lru[row][indx]++; +        if (cd.valid && replc.lru[row][indx] == 0) +            break; +        for (unsigned i = 1; i < cnf.associativity(); i++) +            replc.lru[row][i]++; +        replc.lru[row][indx] = 0;          break;      case MachineConfigCache::RP_LRU: -        replc.lfu[row][indx] = time(NULL); +        replc.lfu[row][indx]++;          break;      default:          break; @@ -345,7 +376,6 @@ void Cache::kick(unsigned associat_indx, unsigned row) const {      switch (cnf.replacement_policy()) {      case MachineConfigCache::RP_LFU: -        replc.lru[row][associat_indx] = 0;          break;      default:          break; diff --git a/qtmips_machine/cache.h b/qtmips_machine/cache.h index d08e66a..200f3ce 100644 --- a/qtmips_machine/cache.h +++ b/qtmips_machine/cache.h @@ -50,7 +50,7 @@ public:      ~Cache();      bool wword(std::uint32_t address, std::uint32_t value); -    std::uint32_t rword(std::uint32_t address) const; +    std::uint32_t rword(std::uint32_t address, bool debug_access = false) const;      void flush(); // flush cache      void sync(); // Same as flush @@ -91,12 +91,13 @@ private:      mutable struct cache_data **dt;      union { -        time_t ** lru; // Access time +        unsigned int ** lru; // Access time          unsigned **lfu; // Access count      } replc; // Data used for replacement policy      mutable unsigned hit_read, miss_read, hit_write, miss_write; // Hit and miss counters +    std::uint32_t debug_rword(std::uint32_t address) const;      bool access(std::uint32_t address, std::uint32_t *data, bool write, std::uint32_t value = 0) const;      void kick(unsigned associat_indx, unsigned row) const;      std::uint32_t base_address(std::uint32_t tag, unsigned row) const; diff --git a/qtmips_machine/memory.cpp b/qtmips_machine/memory.cpp index af9420b..848669d 100644 --- a/qtmips_machine/memory.cpp +++ b/qtmips_machine/memory.cpp @@ -61,18 +61,18 @@ bool MemoryAccess::write_word(std::uint32_t offset, std::uint32_t value) {      return wword(offset, value);  } -std::uint8_t MemoryAccess::read_byte(std::uint32_t offset) const { +std::uint8_t MemoryAccess::read_byte(std::uint32_t offset, bool debug_access) const {      int nth = SH_NTH_8(offset); -    return (std::uint8_t)(rword(offset) >> nth); +    return (std::uint8_t)(rword(offset, debug_access) >> nth);  } -std::uint16_t MemoryAccess::read_hword(std::uint32_t offset) const { +std::uint16_t MemoryAccess::read_hword(std::uint32_t offset, bool debug_access) const {      int nth = SH_NTH_16(offset); -    return (std::uint16_t)(rword(offset) >> nth); +    return (std::uint16_t)(rword(offset, debug_access) >> nth);  } -std::uint32_t MemoryAccess::read_word(std::uint32_t offset) const { -    return rword(offset); +std::uint32_t MemoryAccess::read_word(std::uint32_t offset, bool debug_access) const { +    return rword(offset, debug_access);  }  void MemoryAccess::write_ctl(enum AccessControl ctl, std::uint32_t offset, std::uint32_t value) { @@ -151,7 +151,8 @@ bool MemorySection::wword(std::uint32_t offset, std::uint32_t value) {      return changed;  } -std::uint32_t MemorySection::rword(std::uint32_t offset) const { +std::uint32_t MemorySection::rword(std::uint32_t offset, bool debug_access) const { +    (void)debug_access;      offset = offset >> 2;      if (offset >= this->len)          throw QTMIPS_EXCEPTION(OutOfMemoryAccess, "Trying to read outside of the memory section", QString("Accessing using offset: ") + QString(offset)); @@ -263,12 +264,12 @@ bool Memory::wword(std::uint32_t address, std::uint32_t value) {      return changed;  } -std::uint32_t Memory::rword(std::uint32_t address) const { +std::uint32_t Memory::rword(std::uint32_t address, bool debug_access) const {      MemorySection *section = this->get_section(address, false);      if (section == nullptr)          return 0;      else -        return section->read_word(SECTION_OFFSET_MASK(address)); +        return section->read_word(SECTION_OFFSET_MASK(address), debug_access);  }  bool Memory::operator==(const Memory&m) const { diff --git a/qtmips_machine/memory.h b/qtmips_machine/memory.h index 33caf46..b354c4c 100644 --- a/qtmips_machine/memory.h +++ b/qtmips_machine/memory.h @@ -52,9 +52,9 @@ public:      bool write_hword(std::uint32_t offset, std::uint16_t value);      bool write_word(std::uint32_t offset, std::uint32_t value); -    std::uint8_t read_byte(std::uint32_t offset) const; -    std::uint16_t read_hword(std::uint32_t offset) const; -    std::uint32_t read_word(std::uint32_t offset) const; +    std::uint8_t read_byte(std::uint32_t offset, bool debug_access = false) const; +    std::uint16_t read_hword(std::uint32_t offset, bool debug_access = false) const; +    std::uint32_t read_word(std::uint32_t offset, bool debug_access = false) const;      void write_ctl(enum AccessControl ctl, std::uint32_t offset, std::uint32_t value);      std::uint32_t read_ctl(enum AccessControl ctl, std::uint32_t offset) const; @@ -64,7 +64,7 @@ public:  protected:      virtual bool wword(std::uint32_t offset, std::uint32_t value) = 0; -    virtual std::uint32_t rword(std::uint32_t offset) const = 0; +    virtual std::uint32_t rword(std::uint32_t offset, bool debug_access = false) const = 0;  private:      static int sh_nth(std::uint32_t offset); @@ -77,7 +77,7 @@ public:      ~MemorySection();      bool wword(std::uint32_t offset, std::uint32_t value); -    std::uint32_t rword(std::uint32_t offset) const; +    std::uint32_t rword(std::uint32_t offsetbool, bool debug_access = false) const;      void merge(MemorySection&);      std::uint32_t length() const; @@ -107,7 +107,7 @@ public:      MemorySection *get_section(std::uint32_t address, bool create) const; // returns section containing given address      bool wword(std::uint32_t address, std::uint32_t value); -    std::uint32_t rword(std::uint32_t address) const; +    std::uint32_t rword(std::uint32_t address, bool debug_access = false) const;      bool operator==(const Memory&) const;      bool operator!=(const Memory&) const; diff --git a/qtmips_machine/peripheral.cpp b/qtmips_machine/peripheral.cpp index ac74c2a..9e922b8 100644 --- a/qtmips_machine/peripheral.cpp +++ b/qtmips_machine/peripheral.cpp @@ -55,7 +55,8 @@ bool SimplePeripheral::wword(std::uint32_t address, std::uint32_t value) {      return true;  } -std::uint32_t SimplePeripheral::rword(std::uint32_t address) const { +std::uint32_t SimplePeripheral::rword(std::uint32_t address, bool debug_access) const { +    (void)debug_access;      std::uint32_t value = 0x12345678;  #if 0      printf("SimplePeripheral::rword address 0x%08lx\n", diff --git a/qtmips_machine/peripheral.h b/qtmips_machine/peripheral.h index 92df1d7..0effd47 100644 --- a/qtmips_machine/peripheral.h +++ b/qtmips_machine/peripheral.h @@ -57,7 +57,7 @@ signals:  public:      bool wword(std::uint32_t address, std::uint32_t value); -    std::uint32_t rword(std::uint32_t address) const; +    std::uint32_t rword(std::uint32_t address, bool debug_access = false) const;  };  } diff --git a/qtmips_machine/physaddrspace.cpp b/qtmips_machine/physaddrspace.cpp index bb01b60..4d0045c 100644 --- a/qtmips_machine/physaddrspace.cpp +++ b/qtmips_machine/physaddrspace.cpp @@ -59,11 +59,11 @@ bool PhysAddrSpace::wword(std::uint32_t address, std::uint32_t value) {      return p_range->mem_acces->write_word(address - p_range->start_addr, value);  } -std::uint32_t PhysAddrSpace::rword(std::uint32_t address) const { +std::uint32_t PhysAddrSpace::rword(std::uint32_t address, bool debug_access) const {      const RangeDesc *p_range = find_range(address);      if (p_range == nullptr)          return 0x00000000; -    return p_range->mem_acces->read_word(address - p_range->start_addr); +    return p_range->mem_acces->read_word(address - p_range->start_addr, debug_access);  }  enum LocationStatus PhysAddrSpace::location_status(std::uint32_t address) const { diff --git a/qtmips_machine/physaddrspace.h b/qtmips_machine/physaddrspace.h index c6f5e81..9c13e07 100644 --- a/qtmips_machine/physaddrspace.h +++ b/qtmips_machine/physaddrspace.h @@ -52,7 +52,7 @@ public:      ~PhysAddrSpace();      bool wword(std::uint32_t address, std::uint32_t value); -    std::uint32_t rword(std::uint32_t address) const; +    std::uint32_t rword(std::uint32_t address, bool debug_access = false) const;      bool insert_range(MemoryAccess *mem_acces, std::uint32_t start_addr, std::uint32_t last_addr, bool move_ownership);      bool remove_range(MemoryAccess *mem_acces);  | 
