In cases where a back door is not being requested alongside a packet or request, there needs to be a structure which describes the address range to use, and what type of access the back door should support. It would be possible to make a Packet/Request to carry that information, but those types are actually pretty big, and have a lot of extra overhead which would be overkill for this purpose. Change-Id: I3638361ffa758ee959cb3bc57f7c35f2aa34a36c Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/65751 Reviewed-by: Jason Lowe-Power <power.jg@gmail.com> Maintainer: Gabe Black <gabeblack@google.com> Tested-by: kokoro <noreply+kokoro@google.com>
151 lines
4.6 KiB
C++
151 lines
4.6 KiB
C++
/*
|
|
* Copyright 2019 Google, Inc.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met: redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer;
|
|
* redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution;
|
|
* neither the name of the copyright holders nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#ifndef __MEM_BACKDOOR_HH__
|
|
#define __MEM_BACKDOOR_HH__
|
|
|
|
#include <cstdint>
|
|
#include <functional>
|
|
#include <memory>
|
|
|
|
#include "base/addr_range.hh"
|
|
#include "base/callback.hh"
|
|
|
|
namespace gem5
|
|
{
|
|
|
|
class MemBackdoor
|
|
{
|
|
public:
|
|
// Callbacks from this back door are set up using a callable which accepts
|
|
// a const reference to this back door as their only parameter.
|
|
typedef std::function<void(const MemBackdoor &backdoor)> CbFunction;
|
|
|
|
public:
|
|
enum Flags
|
|
{
|
|
// How data is allowed to be accessed through this backdoor.
|
|
NoAccess = 0x0,
|
|
Readable = 0x1,
|
|
Writeable = 0x2
|
|
};
|
|
|
|
// The range in the guest address space covered by this back door.
|
|
const AddrRange &range() const { return _range; }
|
|
void range(const AddrRange &r) { _range = r; }
|
|
|
|
// A pointer to the data accessible through this back door.
|
|
uint8_t *ptr() const { return _ptr; }
|
|
void ptr(uint8_t *p) { _ptr = p; }
|
|
|
|
/*
|
|
* Helper functions to make it easier to set/check particular flags.
|
|
*/
|
|
|
|
bool readable() const { return _flags & Readable; }
|
|
void
|
|
readable(bool r)
|
|
{
|
|
if (r)
|
|
_flags = (Flags)(_flags | Readable);
|
|
else
|
|
_flags = (Flags)(_flags & ~Readable);
|
|
}
|
|
|
|
bool writeable() const { return _flags & Writeable; }
|
|
void
|
|
writeable(bool w)
|
|
{
|
|
if (w)
|
|
_flags = (Flags)(_flags | Writeable);
|
|
else
|
|
_flags = (Flags)(_flags & ~Writeable);
|
|
}
|
|
|
|
Flags flags() const { return _flags; }
|
|
void flags(Flags f) { _flags = f; }
|
|
|
|
MemBackdoor(AddrRange r, uint8_t *p, Flags flags) :
|
|
_range(r), _ptr(p), _flags(flags)
|
|
{}
|
|
|
|
MemBackdoor() : MemBackdoor(AddrRange(), nullptr, NoAccess)
|
|
{}
|
|
|
|
// Set up a callable to be called when this back door is invalidated. This
|
|
// lets holders update their bookkeeping to remove any references to it,
|
|
// and/or to propogate that invalidation to other interested parties.
|
|
void
|
|
addInvalidationCallback(CbFunction func)
|
|
{
|
|
invalidationCallbacks.push_back([this,func](){ func(*this); });
|
|
}
|
|
|
|
// Notify and clear invalidation callbacks when the data in the backdoor
|
|
// structure is no longer valid/current. The backdoor might then be
|
|
// updated or even deleted without having to worry about stale data being
|
|
// used.
|
|
void
|
|
invalidate()
|
|
{
|
|
invalidationCallbacks.process();
|
|
invalidationCallbacks.clear();
|
|
}
|
|
|
|
private:
|
|
CallbackQueue invalidationCallbacks;
|
|
|
|
AddrRange _range;
|
|
uint8_t *_ptr;
|
|
Flags _flags;
|
|
};
|
|
|
|
typedef MemBackdoor *MemBackdoorPtr;
|
|
|
|
class MemBackdoorReq
|
|
{
|
|
private:
|
|
AddrRange _range;
|
|
MemBackdoor::Flags _flags;
|
|
|
|
public:
|
|
MemBackdoorReq(AddrRange r, MemBackdoor::Flags new_flags) :
|
|
_range(r), _flags(new_flags)
|
|
{}
|
|
|
|
const AddrRange &range() const { return _range; }
|
|
|
|
bool readable() const { return _flags & MemBackdoor::Readable; }
|
|
bool writeable() const { return _flags & MemBackdoor::Writeable; }
|
|
|
|
MemBackdoor::Flags flags() const { return _flags; }
|
|
};
|
|
|
|
} // namespace gem5
|
|
|
|
#endif //__MEM_BACKDOOR_HH__
|