// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
// Debug Unit memory cache: implementation
|
// Debug Unit memory cache: implementation
|
|
|
// Copyright (C) 2008 Embecosm Limited <info@embecosm.com>
|
// Copyright (C) 2008 Embecosm Limited <info@embecosm.com>
|
|
|
// Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
// Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
|
|
// This file is part of the GDB interface to the cycle accurate model of the
|
// This file is part of the GDB interface to the cycle accurate model of the
|
// OpenRISC 1000 based system-on-chip, ORPSoC, built using Verilator.
|
// OpenRISC 1000 based system-on-chip, ORPSoC, built using Verilator.
|
|
|
// This program is free software: you can redistribute it and/or modify it
|
// This program is free software: you can redistribute it and/or modify it
|
// under the terms of the GNU Lesser General Public License as published by
|
// under the terms of the GNU Lesser General Public License as published by
|
// the Free Software Foundation, either version 3 of the License, or (at your
|
// the Free Software Foundation, either version 3 of the License, or (at your
|
// option) any later version.
|
// option) any later version.
|
|
|
// This program is distributed in the hope that it will be useful, but WITHOUT
|
// This program is distributed in the hope that it will be useful, but WITHOUT
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
// License for more details.
|
// License for more details.
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
|
|
// $Id: MemCache.cpp 326 2009-03-07 16:47:31Z jeremy $
|
// $Id: MemCache.cpp 326 2009-03-07 16:47:31Z jeremy $
|
|
|
#include <cstring>
|
#include <cstring>
|
|
|
#include "MemCache.h"
|
#include "MemCache.h"
|
|
|
|
|
//! Constructor
|
//! Constructor
|
|
|
//! Allocate a closed hash table of the specified size and clear it.
|
//! Allocate a closed hash table of the specified size and clear it.
|
|
|
//! @param[in] _tableSize The desire hash table size. A prime number is
|
//! @param[in] _tableSize The desire hash table size. A prime number is
|
//! recommended.
|
//! recommended.
|
|
|
MemCache::MemCache (int _tableSize) :
|
MemCache::MemCache(int _tableSize):tableSize(_tableSize)
|
tableSize (_tableSize)
|
|
{
|
{
|
tabIsValid = new bool [tableSize];
|
tabIsValid = new bool[tableSize];
|
tabKeyAddr = new uint32_t [tableSize];
|
tabKeyAddr = new uint32_t[tableSize];
|
tabValue = new uint32_t [tableSize];
|
tabValue = new uint32_t[tableSize];
|
|
|
clear ();
|
clear();
|
|
|
} // MemCache ()
|
} // MemCache ()
|
|
|
|
|
//! Destructor
|
//! Destructor
|
|
|
//! Free the hash table arrays
|
//! Free the hash table arrays
|
|
|
MemCache::~MemCache ()
|
MemCache::~MemCache()
|
{
|
{
|
delete [] tabIsValid;
|
delete[]tabIsValid;
|
delete [] tabKeyAddr;
|
delete[]tabKeyAddr;
|
delete [] tabValue;
|
delete[]tabValue;
|
|
|
} // ~MemCache ()
|
} // ~MemCache ()
|
|
|
|
|
//! Empty the hash table
|
//! Empty the hash table
|
|
|
//! Only need to worry about the validity field
|
//! Only need to worry about the validity field
|
void
|
void
|
MemCache::clear ()
|
MemCache::clear()
|
{
|
{
|
memset (tabIsValid, false, sizeof (tabIsValid));
|
memset(tabIsValid, false, sizeof(tabIsValid));
|
|
|
} // clear ()
|
} // clear ()
|
|
|
|
|
//! Write a new value into the hash table
|
//! Write a new value into the hash table
|
|
|
//! Will trash anything already there.
|
//! Will trash anything already there.
|
|
|
//! @param[in] addr The address being written to
|
//! @param[in] addr The address being written to
|
//! @param[in] value The value to write
|
//! @param[in] value The value to write
|
void
|
void MemCache::write(uint32_t addr, uint32_t value)
|
MemCache::write (uint32_t addr,
|
|
uint32_t value)
|
|
{
|
{
|
int keyAddr = addr % tableSize;
|
int keyAddr = addr % tableSize;
|
|
|
tabIsValid[keyAddr] = true;
|
tabIsValid[keyAddr] = true;
|
tabKeyAddr[keyAddr] = addr;
|
tabKeyAddr[keyAddr] = addr;
|
tabValue[keyAddr] = value;
|
tabValue[keyAddr] = value;
|
|
|
} // write ()
|
} // write ()
|
|
|
|
|
//! Try to read a value from the hash table
|
//! Try to read a value from the hash table
|
|
|
//! The entry must be valid and the address must match
|
//! The entry must be valid and the address must match
|
|
|
//! @param[in] addr The address being read from
|
//! @param[in] addr The address being read from
|
//! @param[out] value The value read, if there was one there
|
//! @param[out] value The value read, if there was one there
|
|
|
//! @return True if the value was found in the hash table
|
//! @return True if the value was found in the hash table
|
|
|
bool
|
bool MemCache::read(uint32_t addr, uint32_t & value)
|
MemCache::read (uint32_t addr,
|
|
uint32_t &value)
|
|
{
|
{
|
int keyAddr = addr % tableSize;
|
int keyAddr = addr % tableSize;
|
|
|
if (tabIsValid[keyAddr] & (tabKeyAddr[keyAddr] == addr))
|
if (tabIsValid[keyAddr] & (tabKeyAddr[keyAddr] == addr)) {
|
{
|
|
value = tabValue[keyAddr];
|
value = tabValue[keyAddr];
|
return true;
|
return true;
|
}
|
} else {
|
else
|
|
{
|
|
return false;
|
return false;
|
}
|
}
|
} // read ()
|
} // read ()
|
|
|